[{"data":1,"prerenderedAt":15910},["ShallowReactive",2],{"navigation":3,"/microservices-with-django/securing-microservices":1016,"/microservices-with-django/securing-microservices-surround":15905},[4,54,89,123,165,211,253,331,389,439,462,488,514,540,578,624,650,672,702,736,774,800,850,856,862,868,874,928],{"title":5,"path":6,"stem":7,"children":8},"Introduction and Foundations","/introduction-and-foundations","01.introduction-and-foundations/01.index",[9,10,14,18,22,26,30,34,38,42,46,50],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"What is Django","/introduction-and-foundations/what-is-django","01.introduction-and-foundations/02.what-is-django",{"title":15,"path":16,"stem":17},"Key Concepts and Philosophy","/introduction-and-foundations/key-concepts-and-philosophy","01.introduction-and-foundations/03.key-concepts-and-philosophy",{"title":19,"path":20,"stem":21},"MVC vs MVT: Understanding Django's Architecture","/introduction-and-foundations/mvc-vs-mvt","01.introduction-and-foundations/04.mvc-vs-mvt",{"title":23,"path":24,"stem":25},"Project Structure Overview","/introduction-and-foundations/project-structure-overview","01.introduction-and-foundations/05.project-structure-overview",{"title":27,"path":28,"stem":29},"Installing Django","/introduction-and-foundations/installing-django","01.introduction-and-foundations/06.installing-django",{"title":31,"path":32,"stem":33},"Creating Your First Django Project","/introduction-and-foundations/creating-first-project","01.introduction-and-foundations/07.creating-first-project",{"title":35,"path":36,"stem":37},"Creating Your First Django App","/introduction-and-foundations/creating-first-app","01.introduction-and-foundations/08.creating-first-app",{"title":39,"path":40,"stem":41},"Your First Django \"Hello World\"","/introduction-and-foundations/hello-world","01.introduction-and-foundations/09.hello-world",{"title":43,"path":44,"stem":45},"Django Quick Start Guide","/introduction-and-foundations/quick-start-guide","01.introduction-and-foundations/10.quick-start-guide",{"title":47,"path":48,"stem":49},"How Django Handles Requests","/introduction-and-foundations/how-django-handles-requests","01.introduction-and-foundations/11.how-django-handles-requests",{"title":51,"path":52,"stem":53},"Django Settings","/introduction-and-foundations/django-settings","01.introduction-and-foundations/12.django-settings",{"title":55,"path":56,"stem":57,"children":58},"The Development Environment","/development-environment","02.development-environment/1.index",[59,61,65,69,73,77,81,85],{"title":60,"path":56,"stem":57},"Development Environment",{"title":62,"path":63,"stem":64},"Recommended Tooling for Django Development","/development-environment/recommended-tooling","02.development-environment/2.recommended-tooling",{"title":66,"path":67,"stem":68},"Virtual Environments","/development-environment/virtual-environments","02.development-environment/3.virtual-environments",{"title":70,"path":71,"stem":72},"Django Admin and Management Commands","/development-environment/admin-and-management-commands","02.development-environment/4.admin-and-management-commands",{"title":74,"path":75,"stem":76},"Django Project Settings","/development-environment/project-settings","02.development-environment/5.project-settings",{"title":78,"path":79,"stem":80},"Managing Django Environments: Local, Staging, and Production","/development-environment/environments-local-staging-production","02.development-environment/6.environments-local-staging-production",{"title":82,"path":83,"stem":84},"Running Django Development Server","/development-environment/running-development-server","02.development-environment/7.running-development-server",{"title":86,"path":87,"stem":88},"Working with Django Shell","/development-environment/working-with-shell","02.development-environment/8.working-with-shell",{"title":90,"path":91,"stem":92,"children":93},"Templates and Presentation Layer","/templates-and-presentation","03.templates-and-presentation/1.index",[94,95,99,103,107,111,115,119],{"title":90,"path":91,"stem":92},{"title":96,"path":97,"stem":98},"Introduction to Django Templates","/templates-and-presentation/introduction-to-templates","03.templates-and-presentation/2.introduction-to-templates",{"title":100,"path":101,"stem":102},"The Django Template Language","/templates-and-presentation/django-template-language","03.templates-and-presentation/3.django-template-language",{"title":104,"path":105,"stem":106},"Template Inheritance","/templates-and-presentation/template-inheritance","03.templates-and-presentation/4.template-inheritance",{"title":108,"path":109,"stem":110},"Built-in Template Tags and Filters","/templates-and-presentation/built-in-template-tags-and-filters","03.templates-and-presentation/5.built-in-template-tags-and-filters",{"title":112,"path":113,"stem":114},"Including Static Files","/templates-and-presentation/including-static-files","03.templates-and-presentation/6.including-static-files",{"title":116,"path":117,"stem":118},"Working with Media Files","/templates-and-presentation/working-with-media-files","03.templates-and-presentation/7.working-with-media-files",{"title":120,"path":121,"stem":122},"Using Alternative Template Engines","/templates-and-presentation/using-alternative-template-engines","03.templates-and-presentation/8.using-alternative-template-engines",{"title":124,"path":125,"stem":126,"children":127},"URLs and Views","/urls-and-views","04.urls-and-views/01.index",[128,129,133,137,141,145,149,153,157,161],{"title":124,"path":125,"stem":126},{"title":130,"path":131,"stem":132},"The URL Dispatcher","/urls-and-views/the-url-dispatcher","04.urls-and-views/02.the-url-dispatcher",{"title":134,"path":135,"stem":136},"Writing Function-Based Views","/urls-and-views/writing-function-based-views","04.urls-and-views/03.writing-function-based-views",{"title":138,"path":139,"stem":140},"View Decorators","/urls-and-views/view-decorators","04.urls-and-views/04.view-decorators",{"title":142,"path":143,"stem":144},"Rendering Responses","/urls-and-views/rendering-responses","04.urls-and-views/05.rendering-responses",{"title":146,"path":147,"stem":148},"Redirects","/urls-and-views/redirects","04.urls-and-views/06.redirects",{"title":150,"path":151,"stem":152},"Handling HTTP Methods","/urls-and-views/handling-http-methods","04.urls-and-views/07.handling-http-methods",{"title":154,"path":155,"stem":156},"Conditional View Processing","/urls-and-views/conditional-view-processing","04.urls-and-views/08.conditional-view-processing",{"title":158,"path":159,"stem":160},"File Uploads","/urls-and-views/file-uploads","04.urls-and-views/09.file-uploads",{"title":162,"path":163,"stem":164},"Using Django Shortcut Functions","/urls-and-views/using-django-shortcut-functions","04.urls-and-views/10.using-django-shortcut-functions",{"title":166,"path":167,"stem":168,"children":169},"Class Based Views","/class-based-views","05.class-based-views/01.index",[170,171,175,179,183,187,191,195,199,203,207],{"title":166,"path":167,"stem":168},{"title":172,"path":173,"stem":174},"Introduction to Class-Based Views","/class-based-views/introduction-to-class-based-views","05.class-based-views/02.introduction-to-class-based-views",{"title":176,"path":177,"stem":178},"Common Base Classes","/class-based-views/common-base-classes","05.class-based-views/03.common-base-classes",{"title":180,"path":181,"stem":182},"Built-in Generic Views","/class-based-views/built-in-generic-views","05.class-based-views/04.built-in-generic-views",{"title":184,"path":185,"stem":186},"Views for CRUD Operations","/class-based-views/views-for-crud-operations","05.class-based-views/05.views-for-crud-operations",{"title":188,"path":189,"stem":190},"Handling Forms with Class-Based Views","/class-based-views/handling-forms-with-class-based-views","05.class-based-views/06.handling-forms-with-class-based-views",{"title":192,"path":193,"stem":194},"Using Mixins","/class-based-views/using-mixins","05.class-based-views/07.using-mixins",{"title":196,"path":197,"stem":198},"URL Configuration with Class-Based Views","/class-based-views/url-configuration-with-class-based-views","05.class-based-views/08.url-configuration-with-class-based-views",{"title":200,"path":201,"stem":202},"Subclassing Generic Views","/class-based-views/subclassing-generic-views","05.class-based-views/09.subclassing-generic-views",{"title":204,"path":205,"stem":206},"Asynchronous Class-Based Views","/class-based-views/asynchronous-class-based-views","05.class-based-views/10.asynchronous-class-based-views",{"title":208,"path":209,"stem":210},"Pagination","/class-based-views/pagination","05.class-based-views/11.pagination",{"title":212,"path":213,"stem":214,"children":215},"Forms and User Input","/forms-and-user-input","06.forms-and-user-input/01.index",[216,217,221,225,229,233,237,241,245,249],{"title":212,"path":213,"stem":214},{"title":218,"path":219,"stem":220},"Understanding HTML Forms","/forms-and-user-input/understanding-html-forms","06.forms-and-user-input/02.understanding-html-forms",{"title":222,"path":223,"stem":224},"Django's Role in Form Handling","/forms-and-user-input/djangos-role-in-form-handling","06.forms-and-user-input/03.djangos-role-in-form-handling",{"title":226,"path":227,"stem":228},"Creating Forms with Forms API","/forms-and-user-input/creating-forms-with-forms-api","06.forms-and-user-input/04.creating-forms-with-forms-api",{"title":230,"path":231,"stem":232},"Form Validation","/forms-and-user-input/form-validation","06.forms-and-user-input/05.form-validation",{"title":234,"path":235,"stem":236},"Built-in Fields and Widgets","/forms-and-user-input/built-in-fields-and-widgets","06.forms-and-user-input/06.built-in-fields-and-widgets",{"title":238,"path":239,"stem":240},"Form Rendering in Templates","/forms-and-user-input/form-rendering-in-templates","06.forms-and-user-input/07.form-rendering-in-templates",{"title":242,"path":243,"stem":244},"Model Forms","/forms-and-user-input/model-forms","06.forms-and-user-input/08.model-forms",{"title":246,"path":247,"stem":248},"Advanced Form Techniques","/forms-and-user-input/advanced-form-techniques","06.forms-and-user-input/09.advanced-form-techniques",{"title":250,"path":251,"stem":252},"Security Considerations for Forms","/forms-and-user-input/security-considerations-for-forms","06.forms-and-user-input/10.security-considerations-for-forms",{"title":254,"path":255,"stem":256,"children":257},"Models and Databases","/models-and-databases","07.models-and-databases/01.index",[258,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327],{"title":254,"path":255,"stem":256},{"title":260,"path":261,"stem":262},"Understanding Django Models","/models-and-databases/understanding-django-models","07.models-and-databases/02.understanding-django-models",{"title":264,"path":265,"stem":266},"Defining Fields","/models-and-databases/defining-fields","07.models-and-databases/03.defining-fields",{"title":268,"path":269,"stem":270},"Relationships and Foreign Keys","/models-and-databases/relationships-and-foreign-keys","07.models-and-databases/04.relationships-and-foreign-keys",{"title":272,"path":273,"stem":274},"Examples of Relationship Patterns","/models-and-databases/examples-of-relationship-patterns","07.models-and-databases/05.examples-of-relationship-patterns",{"title":276,"path":277,"stem":278},"Making Queries","/models-and-databases/making-queries","07.models-and-databases/06.making-queries",{"title":280,"path":281,"stem":282},"Filtering, Ordering, and Slicing","/models-and-databases/filtering-ordering-slicing","07.models-and-databases/07.filtering-ordering-slicing",{"title":284,"path":285,"stem":286},"Managers and QuerySets","/models-and-databases/managers-and-querysets","07.models-and-databases/08.managers-and-querysets",{"title":288,"path":289,"stem":290},"Aggregation","/models-and-databases/aggregation","07.models-and-databases/09.aggregation",{"title":292,"path":293,"stem":294},"Search","/models-and-databases/search","07.models-and-databases/10.search",{"title":296,"path":297,"stem":298},"Raw SQL Queries","/models-and-databases/raw-sql-queries","07.models-and-databases/11.raw-sql-queries",{"title":300,"path":301,"stem":302},"Transactions","/models-and-databases/transactions","07.models-and-databases/12.transactions",{"title":304,"path":305,"stem":306},"Multiple Databases","/models-and-databases/multiple-databases","07.models-and-databases/13.multiple-databases",{"title":308,"path":309,"stem":310},"Tablespaces","/models-and-databases/tablespaces","07.models-and-databases/14.tablespaces",{"title":312,"path":313,"stem":314},"Composite Primary Keys","/models-and-databases/composite-primary-keys","07.models-and-databases/15.composite-primary-keys",{"title":316,"path":317,"stem":318},"Database Instrumentation","/models-and-databases/database-instrumentation","07.models-and-databases/16.database-instrumentation",{"title":320,"path":321,"stem":322},"Database Optimization","/models-and-databases/database-optimization","07.models-and-databases/17.database-optimization",{"title":324,"path":325,"stem":326},"Fixtures","/models-and-databases/fixtures","07.models-and-databases/18.fixtures",{"title":328,"path":329,"stem":330},"Signals","/models-and-databases/signals","07.models-and-databases/19.signals",{"title":332,"path":333,"stem":334,"children":335},"Migrations","/migrations","08.migrations/01.index",[336,337,341,345,349,353,357,361,365,369,373,377,381,385],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"How Migrations Work","/migrations/how-migrations-work","08.migrations/02.how-migrations-work",{"title":342,"path":343,"stem":344},"Management Commands","/migrations/management-commands","08.migrations/03.management-commands",{"title":346,"path":347,"stem":348},"Dependencies and Workflow","/migrations/dependencies-and-workflow","08.migrations/04.dependencies-and-workflow",{"title":350,"path":351,"stem":352},"Transaction Handling","/migrations/transaction-handling","08.migrations/05.transaction-handling",{"title":354,"path":355,"stem":356},"Adding Migrations to Apps","/migrations/adding-migrations-to-apps","08.migrations/06.adding-migrations-to-apps",{"title":358,"path":359,"stem":360},"Reversing Migrations","/migrations/reversing-migrations","08.migrations/07.reversing-migrations",{"title":362,"path":363,"stem":364},"Historical Models","/migrations/historical-models","08.migrations/08.historical-models",{"title":366,"path":367,"stem":368},"Considerations When Removing Fields","/migrations/considerations-when-removing-fields","08.migrations/09.considerations-when-removing-fields",{"title":370,"path":371,"stem":372},"Data Migrations","/migrations/data-migrations","08.migrations/10.data-migrations",{"title":374,"path":375,"stem":376},"Squashing Migrations","/migrations/squashing-migrations","08.migrations/11.squashing-migrations",{"title":378,"path":379,"stem":380},"Serializing Values","/migrations/serializing-values","08.migrations/12.serializing-values",{"title":382,"path":383,"stem":384},"Supporting Multiple Django Versions","/migrations/supporting-multiple-django-versions","08.migrations/13.supporting-multiple-django-versions",{"title":386,"path":387,"stem":388},"Django Serialization Framework","/migrations/django-serialization-framework","08.migrations/14.django-serialization-framework",{"title":390,"path":391,"stem":392,"children":393},"Authentication and Authorization","/authentication-and-authorization","09.authentication-and-authorization/01.index",[394,395,399,403,407,411,415,419,423,427,431,435],{"title":390,"path":391,"stem":392},{"title":396,"path":397,"stem":398},"Overview of Django's Authentication System","/authentication-and-authorization/overview-of-django-authentication-system","09.authentication-and-authorization/02.overview-of-django-authentication-system",{"title":400,"path":401,"stem":402},"Users and Groups","/authentication-and-authorization/users-and-groups","09.authentication-and-authorization/03.users-and-groups",{"title":404,"path":405,"stem":406},"Permissions","/authentication-and-authorization/permissions","09.authentication-and-authorization/04.permissions",{"title":408,"path":409,"stem":410},"Password Management","/authentication-and-authorization/password-management","09.authentication-and-authorization/05.password-management",{"title":412,"path":413,"stem":414},"Authentication Views","/authentication-and-authorization/authentication-views","09.authentication-and-authorization/06.authentication-views",{"title":416,"path":417,"stem":418},"Login and Logout","/authentication-and-authorization/login-and-logout","09.authentication-and-authorization/07.login-and-logout",{"title":420,"path":421,"stem":422},"Custom User Models","/authentication-and-authorization/custom-user-models","09.authentication-and-authorization/08.custom-user-models",{"title":424,"path":425,"stem":426},"Middleware for Authentication","/authentication-and-authorization/middleware-for-authentication","09.authentication-and-authorization/09.middleware-for-authentication",{"title":428,"path":429,"stem":430},"Authorization in Views and Templates","/authentication-and-authorization/authorization-in-views-and-templates","09.authentication-and-authorization/10.authorization-in-views-and-templates",{"title":432,"path":433,"stem":434},"Integrating Social Authentication","/authentication-and-authorization/integrating-social-authentication","09.authentication-and-authorization/11.integrating-social-authentication",{"title":436,"path":437,"stem":438},"Security Best Practices","/authentication-and-authorization/security-best-practices","09.authentication-and-authorization/12.security-best-practices",{"title":440,"path":441,"stem":442,"children":443},"Sessions, Cookies, and State","/sessions-cookies-state","10.sessions-cookies-state/01.index",[444,446,450,454,458],{"title":445,"path":441,"stem":442},"Sessions, Cookies, and State Management",{"title":447,"path":448,"stem":449},"Introduction to Sessions","/sessions-cookies-state/introduction-to-sessions","10.sessions-cookies-state/02.introduction-to-sessions",{"title":451,"path":452,"stem":453},"Working with Cookies","/sessions-cookies-state/working-with-cookies","10.sessions-cookies-state/03.working-with-cookies",{"title":455,"path":456,"stem":457},"Server-Side Session Storage Options","/sessions-cookies-state/server-side-session-storage-options","10.sessions-cookies-state/04.server-side-session-storage-options",{"title":459,"path":460,"stem":461},"Session Security","/sessions-cookies-state/session-security","10.sessions-cookies-state/05.session-security",{"title":463,"path":464,"stem":465,"children":466},"Working with Files","/working-with-files","11.working-with-files/01.index",[467,468,472,476,480,484],{"title":463,"path":464,"stem":465},{"title":469,"path":470,"stem":471},"Files in Models","/working-with-files/files-in-models","11.working-with-files/02.files-in-models",{"title":473,"path":474,"stem":475},"The File Object","/working-with-files/the-file-object","11.working-with-files/03.the-file-object",{"title":477,"path":478,"stem":479},"Storage Backends","/working-with-files/storage-backends","11.working-with-files/04.storage-backends",{"title":481,"path":482,"stem":483},"Using Cloud Storage Providers","/working-with-files/using-cloud-storage-providers","11.working-with-files/05.using-cloud-storage-providers",{"title":485,"path":486,"stem":487},"Managing Media in Production","/working-with-files/managing-media-in-production","11.working-with-files/06.managing-media-in-production",{"title":489,"path":490,"stem":491,"children":492},"Admin Site","/admin-site","12.admin-site/01.index",[493,494,498,502,506,510],{"title":489,"path":490,"stem":491},{"title":495,"path":496,"stem":497},"Enabling the Admin","/admin-site/enabling-the-admin","12.admin-site/02.enabling-the-admin",{"title":499,"path":500,"stem":501},"Registering Models","/admin-site/registering-models","12.admin-site/03.registering-models",{"title":503,"path":504,"stem":505},"Customizing Admin Display","/admin-site/customizing-admin-display","12.admin-site/04.customizing-admin-display",{"title":507,"path":508,"stem":509},"Admin Actions","/admin-site/admin-actions","12.admin-site/05.admin-actions",{"title":511,"path":512,"stem":513},"Admin Security Best Practices","/admin-site/admin-security-best-practices","12.admin-site/06.admin-security-best-practices",{"title":515,"path":516,"stem":517,"children":518},"Middleware","/middleware","13.middleware/01.index",[519,520,524,528,532,536],{"title":515,"path":516,"stem":517},{"title":521,"path":522,"stem":523},"Middleware Overview","/middleware/middleware-overview","13.middleware/02.middleware-overview",{"title":525,"path":526,"stem":527},"Built-in Middleware","/middleware/built-in-middleware","13.middleware/03.built-in-middleware",{"title":529,"path":530,"stem":531},"Creating Custom Middleware","/middleware/creating-custom-middleware","13.middleware/04.creating-custom-middleware",{"title":533,"path":534,"stem":535},"Middleware Ordering","/middleware/middleware-ordering","13.middleware/05.middleware-ordering",{"title":537,"path":538,"stem":539},"Performance and Debugging","/middleware/performance-and-debugging","13.middleware/06.performance-and-debugging",{"title":541,"path":542,"stem":543,"children":544},"Security","/security","14.security/01.index",[545,546,550,554,558,562,566,570,574],{"title":541,"path":542,"stem":543},{"title":547,"path":548,"stem":549},"Django Security Philosophy","/security/django-security-philosophy","14.security/02.django-security-philosophy",{"title":551,"path":552,"stem":553},"Cross Site Request Forgery","/security/cross-site-request-forgery","14.security/03.cross-site-request-forgery",{"title":555,"path":556,"stem":557},"Cross Site Scripting","/security/cross-site-scripting","14.security/04.cross-site-scripting",{"title":559,"path":560,"stem":561},"SQL Injection Protection","/security/sql-injection-protection","14.security/05.sql-injection-protection",{"title":563,"path":564,"stem":565},"Clickjacking Protection","/security/clickjacking-protection","14.security/06.clickjacking-protection",{"title":567,"path":568,"stem":569},"HTTPS Setup and HSTS","/security/https-setup-and-hsts","14.security/07.https-setup-and-hsts",{"title":571,"path":572,"stem":573},"Password Storage and Cryptography","/security/password-storage-and-cryptography","14.security/08.password-storage-and-cryptography",{"title":575,"path":576,"stem":577},"Secure Deployment Checklist","/security/secure-deployment-checklist","14.security/09.secure-deployment-checklist",{"title":579,"path":580,"stem":581,"children":582},"Testing","/testing","15.testing/01.index",[583,584,588,592,596,600,604,608,612,616,620],{"title":579,"path":580,"stem":581},{"title":585,"path":586,"stem":587},"Introduction to Django Testing","/testing/introduction-to-django-testing","15.testing/02.introduction-to-django-testing",{"title":589,"path":590,"stem":591},"Writing and Running Tests","/testing/writing-and-running-tests","15.testing/03.writing-and-running-tests",{"title":593,"path":594,"stem":595},"Test Tools","/testing/test-tools","15.testing/04.test-tools",{"title":597,"path":598,"stem":599},"Testing Models","/testing/testing-models","15.testing/05.testing-models",{"title":601,"path":602,"stem":603},"Testing Views","/testing/testing-views","15.testing/06.testing-views",{"title":605,"path":606,"stem":607},"Testing Forms","/testing/testing-forms","15.testing/07.testing-forms",{"title":609,"path":610,"stem":611},"Testing Templates","/testing/testing-templates","15.testing/08.testing-templates",{"title":613,"path":614,"stem":615},"Testing Authentication","/testing/testing-authentication","15.testing/09.testing-authentication",{"title":617,"path":618,"stem":619},"Advanced Testing Topics","/testing/advanced-testing-topics","15.testing/10.advanced-testing-topics",{"title":621,"path":622,"stem":623},"Performance Testing","/testing/performance-testing","15.testing/11.performance-testing",{"title":625,"path":626,"stem":627,"children":628},"Static Assets and Frontend Integration","/static-assets-and-frontend-integration","16.static-assets-and-frontend-integration/01.index",[629,630,634,638,642,646],{"title":625,"path":626,"stem":627},{"title":631,"path":632,"stem":633},"Working with Static Files","/static-assets-and-frontend-integration/working-with-static-files","16.static-assets-and-frontend-integration/02.working-with-static-files",{"title":635,"path":636,"stem":637},"Integrating CSS and JavaScript","/static-assets-and-frontend-integration/integrating-css-and-javascript","16.static-assets-and-frontend-integration/03.integrating-css-and-javascript",{"title":639,"path":640,"stem":641},"Using Build Tools like Vite or Webpack","/static-assets-and-frontend-integration/using-build-tools-like-vite-or-webpack","16.static-assets-and-frontend-integration/04.using-build-tools-like-vite-or-webpack",{"title":643,"path":644,"stem":645},"Using React or Vue with Django","/static-assets-and-frontend-integration/using-react-or-vue-with-django","16.static-assets-and-frontend-integration/05.using-react-or-vue-with-django",{"title":647,"path":648,"stem":649},"Managing CORS","/static-assets-and-frontend-integration/managing-cors","16.static-assets-and-frontend-integration/06.managing-cors",{"title":651,"path":652,"stem":653,"children":654},"Internationalization and Localization","/internationalization-and-localization","17.internationalization-and-localization/01.index",[655,656,660,664,668],{"title":651,"path":652,"stem":653},{"title":657,"path":658,"stem":659},"Enabling Translation","/internationalization-and-localization/enabling-translation","17.internationalization-and-localization/02.enabling-translation",{"title":661,"path":662,"stem":663},"Translating Text in Code and Templates","/internationalization-and-localization/translating-text-in-code-and-templates","17.internationalization-and-localization/03.translating-text-in-code-and-templates",{"title":665,"path":666,"stem":667},"Timezone Support","/internationalization-and-localization/timezone-support","17.internationalization-and-localization/04.timezone-support",{"title":669,"path":670,"stem":671},"Locale Middleware","/internationalization-and-localization/locale-middleware","17.internationalization-and-localization/05.locale-middleware",{"title":673,"path":674,"stem":675,"children":676},"Caching","/caching","18.caching/01.index",[677,678,682,686,690,694,698],{"title":673,"path":674,"stem":675},{"title":679,"path":680,"stem":681},"Introduction to Caching","/caching/introduction-to-caching","18.caching/02.introduction-to-caching",{"title":683,"path":684,"stem":685},"Cache Backends","/caching/cache-backends","18.caching/03.cache-backends",{"title":687,"path":688,"stem":689},"Per View Caching","/caching/per-view-caching","18.caching/04.per-view-caching",{"title":691,"path":692,"stem":693},"Low Level Cache API","/caching/low-level-cache-api","18.caching/05.low-level-cache-api",{"title":695,"path":696,"stem":697},"Template Fragment Caching","/caching/template-fragment-caching","18.caching/06.template-fragment-caching",{"title":699,"path":700,"stem":701},"Deployment Level Caching Patterns","/caching/deployment-level-caching-patterns","18.caching/07.deployment-level-caching-patterns",{"title":703,"path":704,"stem":705,"children":706},"Asynchronous Django","/asynchronous-django","19.asynchronous-django/01.index",[707,708,712,716,720,724,728,732],{"title":703,"path":704,"stem":705},{"title":709,"path":710,"stem":711},"Introduction to ASGI","/asynchronous-django/introduction-to-asgi","19.asynchronous-django/02.introduction-to-asgi",{"title":713,"path":714,"stem":715},"Async Views","/asynchronous-django/async-views","19.asynchronous-django/03.async-views",{"title":717,"path":718,"stem":719},"Async ORM Status","/asynchronous-django/async-orm-status","19.asynchronous-django/04.async-orm-status",{"title":721,"path":722,"stem":723},"WebSockets with Channels","/asynchronous-django/websockets-with-channels","19.asynchronous-django/05.websockets-with-channels",{"title":725,"path":726,"stem":727},"Background Tasks with Celery or RQ","/asynchronous-django/background-tasks-with-celery-or-rq","19.asynchronous-django/06.background-tasks-with-celery-or-rq",{"title":729,"path":730,"stem":731},"Asynchronous Support","/asynchronous-django/asynchronous-support","19.asynchronous-django/07.asynchronous-support",{"title":733,"path":734,"stem":735},"Django's Tasks Framework","/asynchronous-django/django-tasks-framework","19.asynchronous-django/08.django-tasks-framework",{"title":737,"path":738,"stem":739,"children":740},"Deployment","/deployment","20.deployment/01.index",[741,742,746,750,754,758,762,766,770],{"title":737,"path":738,"stem":739},{"title":743,"path":744,"stem":745},"Preparing for Production","/deployment/preparing-for-production","20.deployment/02.preparing-for-production",{"title":747,"path":748,"stem":749},"Using WSGI and ASGI Servers","/deployment/using-wsgi-and-asgi-servers","20.deployment/03.using-wsgi-and-asgi-servers",{"title":751,"path":752,"stem":753},"Deploying on Linux Servers","/deployment/deploying-on-linux-servers","20.deployment/04.deploying-on-linux-servers",{"title":755,"path":756,"stem":757},"Using Docker","/deployment/using-docker","20.deployment/05.using-docker",{"title":759,"path":760,"stem":761},"Cloud Deployment Guides","/deployment/cloud-deployment-guides","20.deployment/06.cloud-deployment-guides",{"title":763,"path":764,"stem":765},"Scaling and Load Balancing","/deployment/scaling-and-load-balancing","20.deployment/07.scaling-and-load-balancing",{"title":767,"path":768,"stem":769},"Monitoring and Logging","/deployment/monitoring-and-logging","20.deployment/08.monitoring-and-logging",{"title":771,"path":772,"stem":773},"Backup Strategies","/deployment/backup-strategies","20.deployment/09.backup-strategies",{"title":775,"path":776,"stem":777,"children":778},"Performance and Optimization","/performance-and-optimization","21.performance-and-optimization/01.index",[779,780,784,788,792,796],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Query Optimization","/performance-and-optimization/query-optimization","21.performance-and-optimization/02.query-optimization",{"title":785,"path":786,"stem":787},"Template Rendering Optimization","/performance-and-optimization/template-rendering-optimization","21.performance-and-optimization/03.template-rendering-optimization",{"title":789,"path":790,"stem":791},"Using Select Related and Prefetch Related","/performance-and-optimization/using-select-related-and-prefetch-related","21.performance-and-optimization/04.using-select-related-and-prefetch-related",{"title":793,"path":794,"stem":795},"Caching Strategies","/performance-and-optimization/caching-strategies","21.performance-and-optimization/05.caching-strategies",{"title":797,"path":798,"stem":799},"Profiling Django Apps","/performance-and-optimization/profiling-django-apps","21.performance-and-optimization/06.profiling-django-apps",{"title":801,"path":802,"stem":803,"children":804},"Advanced and Expert Topics","/advanced-and-expert-topics","22.advanced-and-expert-topics/01.index",[805,806,810,814,818,822,826,830,834,838,842,846],{"title":801,"path":802,"stem":803},{"title":807,"path":808,"stem":809},"System Architecture Patterns","/advanced-and-expert-topics/system-architecture-patterns","22.advanced-and-expert-topics/02.system-architecture-patterns",{"title":811,"path":812,"stem":813},"Domain Driven Design with Django","/advanced-and-expert-topics/domain-driven-design-with-django","22.advanced-and-expert-topics/03.domain-driven-design-with-django",{"title":815,"path":816,"stem":817},"Building Large Scale Django Projects","/advanced-and-expert-topics/building-large-scale-django-projects","22.advanced-and-expert-topics/04.building-large-scale-django-projects",{"title":819,"path":820,"stem":821},"Plugin Architectures for Django Apps","/advanced-and-expert-topics/plugin-architectures-for-django-apps","22.advanced-and-expert-topics/05.plugin-architectures-for-django-apps",{"title":823,"path":824,"stem":825},"Extending Django's Core","/advanced-and-expert-topics/extending-djangos-core","22.advanced-and-expert-topics/06.extending-djangos-core",{"title":827,"path":828,"stem":829},"Custom ORM Expressions","/advanced-and-expert-topics/custom-orm-expressions","22.advanced-and-expert-topics/07.custom-orm-expressions",{"title":831,"path":832,"stem":833},"Custom Management Commands","/advanced-and-expert-topics/custom-management-commands","22.advanced-and-expert-topics/08.custom-management-commands",{"title":835,"path":836,"stem":837},"Working with Signals","/advanced-and-expert-topics/working-with-signals","22.advanced-and-expert-topics/09.working-with-signals",{"title":839,"path":840,"stem":841},"Building Reusable Django Packages","/advanced-and-expert-topics/building-reusable-django-packages","22.advanced-and-expert-topics/10.building-reusable-django-packages",{"title":843,"path":844,"stem":845},"Integrating Microservices","/advanced-and-expert-topics/integrating-microservices","22.advanced-and-expert-topics/11.integrating-microservices",{"title":847,"path":848,"stem":849},"Advanced Security Hardening","/advanced-and-expert-topics/advanced-security-hardening","22.advanced-and-expert-topics/12.advanced-security-hardening",{"title":851,"path":852,"stem":853,"children":854},"Logging in Django","/logging-in-django","23.logging-in-django/01.index",[855],{"title":851,"path":852,"stem":853},{"title":857,"path":858,"stem":859,"children":860},"FAQ and Troubleshooting","/faq-and-troubleshooting","24.faq-and-troubleshooting/01.index",[861],{"title":857,"path":858,"stem":859},{"title":863,"path":864,"stem":865,"children":866},"External Packages and Ecosystem","/external-packages-and-ecosystem","25.external-packages-and-ecosystem/01.index",[867],{"title":863,"path":864,"stem":865},{"title":869,"path":870,"stem":871,"children":872},"Django Internals and Contributing","/django-internals-and-contributing","26.django-internals-and-contributing/01.index",[873],{"title":869,"path":870,"stem":871},{"title":875,"path":876,"stem":877,"children":878},"Microservices with Django","/microservices-with-django","27.microservices-with-django/01.index",[879,880,884,888,892,896,900,904,908,912,916,920,924],{"title":875,"path":876,"stem":877},{"title":881,"path":882,"stem":883},"What Is a Microservice?","/microservices-with-django/what-is-a-microservice","27.microservices-with-django/02.what-is-a-microservice",{"title":885,"path":886,"stem":887},"Introducing the Django Microservices Architecture","/microservices-with-django/django-microservices-architecture","27.microservices-with-django/03.django-microservices-architecture",{"title":889,"path":890,"stem":891},"Setting Up the Development and Runtime Environment","/microservices-with-django/development-environment","27.microservices-with-django/04.development-environment",{"title":893,"path":894,"stem":895},"Cloud-native Data Processing with MongoDB","/microservices-with-django/cloud-native-data-processing","27.microservices-with-django/05.cloud-native-data-processing",{"title":897,"path":898,"stem":899},"Creating RESTful APIs for Microservices","/microservices-with-django/restful-apis","27.microservices-with-django/06.restful-apis",{"title":901,"path":902,"stem":903},"Orchestrating Microservices with Celery and RabbitMQ","/microservices-with-django/orchestrating-celery-rabbitmq","27.microservices-with-django/07.orchestrating-celery-rabbitmq",{"title":905,"path":906,"stem":907},"Testing Microservices","/microservices-with-django/testing-microservices","27.microservices-with-django/08.testing-microservices",{"title":909,"path":910,"stem":911},"Deploying Microservices","/microservices-with-django/deploying-microservices","27.microservices-with-django/09.deploying-microservices",{"title":913,"path":914,"stem":915},"Securing Microservices","/microservices-with-django/securing-microservices","27.microservices-with-django/10.securing-microservices",{"title":917,"path":918,"stem":919},"Improving Microservices Performance with Caching","/microservices-with-django/performance-caching","27.microservices-with-django/11.performance-caching",{"title":921,"path":922,"stem":923},"Best Practices","/microservices-with-django/best-practices","27.microservices-with-django/12.best-practices",{"title":925,"path":926,"stem":927},"Transforming a Monolithic Web App into a Microservice version","/microservices-with-django/monolith-to-microservices","27.microservices-with-django/13.monolith-to-microservices",{"title":929,"path":930,"stem":931,"children":932},"Releases","/releases","releases",[933,936,940,944,948,952,956,960,964,968,972,976,980,984,988,992,996,1000,1004,1008,1012],{"title":934,"path":930,"stem":935},"Django Releases","releases/index",{"title":937,"path":938,"stem":939},"Django 5.1.10 release notes","/releases/5.1.10","releases/5.1.10",{"title":941,"path":942,"stem":943},"Django 5.1.11 release notes","/releases/5.1.11","releases/5.1.11",{"title":945,"path":946,"stem":947},"Django 5.1.12 release notes","/releases/5.1.12","releases/5.1.12",{"title":949,"path":950,"stem":951},"Django 5.1.13 release notes","/releases/5.1.13","releases/5.1.13",{"title":953,"path":954,"stem":955},"Django 5.1.14 release notes","/releases/5.1.14","releases/5.1.14",{"title":957,"path":958,"stem":959},"Django 5.1.15 release notes","/releases/5.1.15","releases/5.1.15",{"title":961,"path":962,"stem":963},"Django 5.2 release notes","/releases/5.2","releases/5.2",{"title":965,"path":966,"stem":967},"Django 5.2.1 release notes","/releases/5.2.1","releases/5.2.1",{"title":969,"path":970,"stem":971},"Django 5.2.10 release notes","/releases/5.2.10","releases/5.2.10",{"title":973,"path":974,"stem":975},"Django 5.2.2 release notes","/releases/5.2.2","releases/5.2.2",{"title":977,"path":978,"stem":979},"Django 5.2.3 release notes","/releases/5.2.3","releases/5.2.3",{"title":981,"path":982,"stem":983},"Django 5.2.4 release notes","/releases/5.2.4","releases/5.2.4",{"title":985,"path":986,"stem":987},"Django 5.2.5 release notes","/releases/5.2.5","releases/5.2.5",{"title":989,"path":990,"stem":991},"Django 5.2.6 release notes","/releases/5.2.6","releases/5.2.6",{"title":993,"path":994,"stem":995},"Django 5.2.7 release notes","/releases/5.2.7","releases/5.2.7",{"title":997,"path":998,"stem":999},"Django 5.2.8 release notes","/releases/5.2.8","releases/5.2.8",{"title":1001,"path":1002,"stem":1003},"Django 5.2.9 release notes","/releases/5.2.9","releases/5.2.9",{"title":1005,"path":1006,"stem":1007},"Django 6.0 release notes","/releases/6.0","releases/6.0",{"title":1009,"path":1010,"stem":1011},"Django 6.0.1 release notes","/releases/6.0.1","releases/6.0.1",{"title":1013,"path":1014,"stem":1015},"Django 6.1 release notes - UNDER DEVELOPMENT","/releases/6.1","releases/6.1",{"id":1017,"title":913,"body":1018,"description":1028,"extension":15900,"links":15901,"meta":15902,"navigation":1219,"path":914,"seo":15903,"stem":915,"__hash__":15904},"docs/27.microservices-with-django/10.securing-microservices.md",{"type":1019,"value":1020,"toc":15869},"minimark",[1021,1025,1029,1034,1039,1080,1083,1087,3482,3486,4229,4233,5033,5037,5041,6332,6336,7046,7049,7053,7889,7893,9350,9353,9357,10580,10584,11693,11696,11700,12420,12424,12847,12851,12855,15015,15019,15822,15826,15829,15862,15865],[1022,1023,913],"h1",{"id":1024},"securing-microservices",[1026,1027,1028],"p",{},"Security in microservices architecture requires a comprehensive approach covering authentication, authorization, network security, data protection, and monitoring. This section explores security best practices and implementation strategies for Django microservices.",[1030,1031,1033],"h2",{"id":1032},"security-challenges-in-microservices","Security Challenges in Microservices",[1035,1036,1038],"h3",{"id":1037},"key-security-concerns","Key Security Concerns",[1040,1041,1042,1050,1056,1062,1068,1074],"ol",{},[1043,1044,1045,1049],"li",{},[1046,1047,1048],"strong",{},"Distributed Authentication",": Managing user identity across services",[1043,1051,1052,1055],{},[1046,1053,1054],{},"Service-to-Service Communication",": Securing inter-service calls",[1043,1057,1058,1061],{},[1046,1059,1060],{},"Network Security",": Protecting communication channels",[1043,1063,1064,1067],{},[1046,1065,1066],{},"Data Protection",": Encrypting sensitive data",[1043,1069,1070,1073],{},[1046,1071,1072],{},"API Security",": Securing external interfaces",[1043,1075,1076,1079],{},[1046,1077,1078],{},"Monitoring",": Detecting security threats",[1030,1081,390],{"id":1082},"authentication-and-authorization",[1035,1084,1086],{"id":1085},"_1-jwt-based-authentication","1. JWT-Based Authentication",[1088,1089,1094],"pre",{"className":1090,"code":1091,"language":1092,"meta":1093,"style":1093},"language-python shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# authentication.py\nimport jwt\nfrom datetime import datetime, timedelta\nfrom django.conf import settings\nfrom django.contrib.auth import get_user_model\nfrom rest_framework.authentication import BaseAuthentication\nfrom rest_framework.exceptions import AuthenticationFailed\n\nUser = get_user_model()\n\nclass JWTAuthentication(BaseAuthentication):\n    \"\"\"JWT token authentication\"\"\"\n    \n    def authenticate(self, request):\n        auth_header = request.META.get('HTTP_AUTHORIZATION')\n        if not auth_header or not auth_header.startswith('Bearer '):\n            return None\n        \n        token = auth_header.split(' ')[1]\n        \n        try:\n            payload = jwt.decode(\n                token, \n                settings.JWT_SECRET_KEY, \n                algorithms=[settings.JWT_ALGORITHM]\n            )\n            \n            user_id = payload.get('user_id')\n            if not user_id:\n                raise AuthenticationFailed('Invalid token payload')\n            \n            user = User.objects.get(id=user_id)\n            if not user.is_active:\n                raise AuthenticationFailed('User account is disabled')\n            \n            return (user, token)\n            \n        except jwt.ExpiredSignatureError:\n            raise AuthenticationFailed('Token has expired')\n        except jwt.InvalidTokenError:\n            raise AuthenticationFailed('Invalid token')\n        except User.DoesNotExist:\n            raise AuthenticationFailed('User not found')\n\nclass JWTTokenGenerator:\n    \"\"\"Generate and validate JWT tokens\"\"\"\n    \n    @staticmethod\n    def generate_access_token(user):\n        \"\"\"Generate access token\"\"\"\n        payload = {\n            'user_id': user.id,\n            'username': user.username,\n            'email': user.email,\n            'exp': datetime.utcnow() + timedelta(minutes=settings.JWT_ACCESS_TOKEN_LIFETIME),\n            'iat': datetime.utcnow(),\n            'type': 'access'\n        }\n        \n        return jwt.encode(\n            payload, \n            settings.JWT_SECRET_KEY, \n            algorithm=settings.JWT_ALGORITHM\n        )\n    \n    @staticmethod\n    def generate_refresh_token(user):\n        \"\"\"Generate refresh token\"\"\"\n        payload = {\n            'user_id': user.id,\n            'exp': datetime.utcnow() + timedelta(days=settings.JWT_REFRESH_TOKEN_LIFETIME),\n            'iat': datetime.utcnow(),\n            'type': 'refresh'\n        }\n        \n        return jwt.encode(\n            payload, \n            settings.JWT_SECRET_KEY, \n            algorithm=settings.JWT_ALGORITHM\n        )\n    \n    @staticmethod\n    def verify_token(token, token_type='access'):\n        \"\"\"Verify token and return payload\"\"\"\n        try:\n            payload = jwt.decode(\n                token, \n                settings.JWT_SECRET_KEY, \n                algorithms=[settings.JWT_ALGORITHM]\n            )\n            \n            if payload.get('type') != token_type:\n                raise jwt.InvalidTokenError('Invalid token type')\n            \n            return payload\n            \n        except jwt.ExpiredSignatureError:\n            raise AuthenticationFailed('Token has expired')\n        except jwt.InvalidTokenError:\n            raise AuthenticationFailed('Invalid token')\n\n# views.py\nfrom rest_framework.decorators import api_view, permission_classes\nfrom rest_framework.permissions import AllowAny\nfrom rest_framework.response import Response\nfrom rest_framework import status\nfrom django.contrib.auth import authenticate\n\n@api_view(['POST'])\n@permission_classes([AllowAny])\ndef login(request):\n    \"\"\"User login endpoint\"\"\"\n    username = request.data.get('username')\n    password = request.data.get('password')\n    \n    if not username or not password:\n        return Response(\n            {'error': 'Username and password required'}, \n            status=status.HTTP_400_BAD_REQUEST\n        )\n    \n    user = authenticate(username=username, password=password)\n    if not user:\n        return Response(\n            {'error': 'Invalid credentials'}, \n            status=status.HTTP_401_UNAUTHORIZED\n        )\n    \n    access_token = JWTTokenGenerator.generate_access_token(user)\n    refresh_token = JWTTokenGenerator.generate_refresh_token(user)\n    \n    return Response({\n        'access_token': access_token,\n        'refresh_token': refresh_token,\n        'user': {\n            'id': user.id,\n            'username': user.username,\n            'email': user.email\n        }\n    })\n\n@api_view(['POST'])\n@permission_classes([AllowAny])\ndef refresh_token(request):\n    \"\"\"Refresh access token\"\"\"\n    refresh_token = request.data.get('refresh_token')\n    \n    if not refresh_token:\n        return Response(\n            {'error': 'Refresh token required'}, \n            status=status.HTTP_400_BAD_REQUEST\n        )\n    \n    try:\n        payload = JWTTokenGenerator.verify_token(refresh_token, 'refresh')\n        user = User.objects.get(id=payload['user_id'])\n        \n        new_access_token = JWTTokenGenerator.generate_access_token(user)\n        \n        return Response({\n            'access_token': new_access_token\n        })\n        \n    except (AuthenticationFailed, User.DoesNotExist) as e:\n        return Response(\n            {'error': str(e)}, \n            status=status.HTTP_401_UNAUTHORIZED\n        )\n","python","",[1095,1096,1097,1106,1117,1138,1157,1179,1197,1214,1221,1237,1242,1263,1277,1283,1307,1343,1380,1390,1396,1428,1433,1442,1461,1472,1487,1507,1513,1519,1545,1558,1578,1583,1615,1632,1650,1655,1673,1678,1693,1712,1726,1744,1758,1776,1781,1791,1801,1806,1816,1830,1841,1852,1874,1894,1914,1959,1980,2000,2006,2011,2026,2036,2050,2065,2071,2076,2083,2097,2107,2116,2135,2174,2193,2211,2216,2221,2234,2243,2256,2269,2274,2279,2286,2314,2324,2331,2346,2355,2368,2383,2388,2393,2422,2444,2449,2457,2462,2475,2492,2505,2522,2527,2533,2555,2572,2589,2602,2622,2627,2649,2664,2680,2690,2719,2748,2753,2773,2783,2810,2826,2831,2836,2864,2875,2884,2908,2922,2927,2932,2953,2974,2979,2990,3008,3025,3038,3057,3076,3094,3099,3105,3110,3127,3140,3153,3163,3190,3195,3206,3215,3239,3252,3257,3262,3270,3298,3336,3341,3361,3366,3375,3389,3395,3400,3429,3438,3464,3477],"code",{"__ignoreMap":1093},[1098,1099,1102],"span",{"class":1100,"line":1101},"line",1,[1098,1103,1105],{"class":1104},"s9Tkl","# authentication.py\n",[1098,1107,1109,1113],{"class":1100,"line":1108},2,[1098,1110,1112],{"class":1111},"siDh9","import",[1098,1114,1116],{"class":1115},"sftqT"," jwt\n",[1098,1118,1120,1123,1126,1128,1131,1135],{"class":1100,"line":1119},3,[1098,1121,1122],{"class":1111},"from",[1098,1124,1125],{"class":1115}," datetime ",[1098,1127,1112],{"class":1111},[1098,1129,1130],{"class":1115}," datetime",[1098,1132,1134],{"class":1133},"soVBu",",",[1098,1136,1137],{"class":1115}," timedelta\n",[1098,1139,1141,1143,1146,1149,1152,1154],{"class":1100,"line":1140},4,[1098,1142,1122],{"class":1111},[1098,1144,1145],{"class":1115}," django",[1098,1147,1148],{"class":1133},".",[1098,1150,1151],{"class":1115},"conf ",[1098,1153,1112],{"class":1111},[1098,1155,1156],{"class":1115}," settings\n",[1098,1158,1160,1162,1164,1166,1169,1171,1174,1176],{"class":1100,"line":1159},5,[1098,1161,1122],{"class":1111},[1098,1163,1145],{"class":1115},[1098,1165,1148],{"class":1133},[1098,1167,1168],{"class":1115},"contrib",[1098,1170,1148],{"class":1133},[1098,1172,1173],{"class":1115},"auth ",[1098,1175,1112],{"class":1111},[1098,1177,1178],{"class":1115}," get_user_model\n",[1098,1180,1182,1184,1187,1189,1192,1194],{"class":1100,"line":1181},6,[1098,1183,1122],{"class":1111},[1098,1185,1186],{"class":1115}," rest_framework",[1098,1188,1148],{"class":1133},[1098,1190,1191],{"class":1115},"authentication ",[1098,1193,1112],{"class":1111},[1098,1195,1196],{"class":1115}," BaseAuthentication\n",[1098,1198,1200,1202,1204,1206,1209,1211],{"class":1100,"line":1199},7,[1098,1201,1122],{"class":1111},[1098,1203,1186],{"class":1115},[1098,1205,1148],{"class":1133},[1098,1207,1208],{"class":1115},"exceptions ",[1098,1210,1112],{"class":1111},[1098,1212,1213],{"class":1115}," AuthenticationFailed\n",[1098,1215,1217],{"class":1100,"line":1216},8,[1098,1218,1220],{"emptyLinePlaceholder":1219},true,"\n",[1098,1222,1224,1227,1230,1234],{"class":1100,"line":1223},9,[1098,1225,1226],{"class":1115},"User ",[1098,1228,1229],{"class":1133},"=",[1098,1231,1233],{"class":1232},"siWMO"," get_user_model",[1098,1235,1236],{"class":1133},"()\n",[1098,1238,1240],{"class":1100,"line":1239},10,[1098,1241,1220],{"emptyLinePlaceholder":1219},[1098,1243,1245,1249,1253,1256,1260],{"class":1100,"line":1244},11,[1098,1246,1248],{"class":1247},"s5Kfy","class",[1098,1250,1252],{"class":1251},"sD-vU"," JWTAuthentication",[1098,1254,1255],{"class":1133},"(",[1098,1257,1259],{"class":1258},"sYn-s","BaseAuthentication",[1098,1261,1262],{"class":1133},"):\n",[1098,1264,1266,1270,1274],{"class":1100,"line":1265},12,[1098,1267,1269],{"class":1268},"sm7ve","    \"\"\"",[1098,1271,1273],{"class":1272},"sVyVU","JWT token authentication",[1098,1275,1276],{"class":1268},"\"\"\"\n",[1098,1278,1280],{"class":1100,"line":1279},13,[1098,1281,1282],{"class":1115},"    \n",[1098,1284,1286,1289,1293,1295,1299,1301,1305],{"class":1100,"line":1285},14,[1098,1287,1288],{"class":1247},"    def",[1098,1290,1292],{"class":1291},"sljsM"," authenticate",[1098,1294,1255],{"class":1133},[1098,1296,1298],{"class":1297},"sRjD_","self",[1098,1300,1134],{"class":1133},[1098,1302,1304],{"class":1303},"sCyAa"," request",[1098,1306,1262],{"class":1133},[1098,1308,1310,1313,1315,1317,1319,1323,1325,1328,1330,1334,1338,1340],{"class":1100,"line":1309},15,[1098,1311,1312],{"class":1115},"        auth_header ",[1098,1314,1229],{"class":1133},[1098,1316,1304],{"class":1115},[1098,1318,1148],{"class":1133},[1098,1320,1322],{"class":1321},"sFGJz","META",[1098,1324,1148],{"class":1133},[1098,1326,1327],{"class":1232},"get",[1098,1329,1255],{"class":1133},[1098,1331,1333],{"class":1332},"sbYkP","'",[1098,1335,1337],{"class":1336},"sTbE_","HTTP_AUTHORIZATION",[1098,1339,1333],{"class":1332},[1098,1341,1342],{"class":1133},")\n",[1098,1344,1346,1349,1353,1356,1359,1361,1364,1366,1369,1371,1373,1376,1378],{"class":1100,"line":1345},16,[1098,1347,1348],{"class":1111},"        if",[1098,1350,1352],{"class":1351},"sVsLi"," not",[1098,1354,1355],{"class":1115}," auth_header ",[1098,1357,1358],{"class":1351},"or",[1098,1360,1352],{"class":1351},[1098,1362,1363],{"class":1115}," auth_header",[1098,1365,1148],{"class":1133},[1098,1367,1368],{"class":1232},"startswith",[1098,1370,1255],{"class":1133},[1098,1372,1333],{"class":1332},[1098,1374,1375],{"class":1336},"Bearer ",[1098,1377,1333],{"class":1332},[1098,1379,1262],{"class":1133},[1098,1381,1383,1386],{"class":1100,"line":1382},17,[1098,1384,1385],{"class":1111},"            return",[1098,1387,1389],{"class":1388},"s8XtY"," None\n",[1098,1391,1393],{"class":1100,"line":1392},18,[1098,1394,1395],{"class":1115},"        \n",[1098,1397,1399,1402,1404,1406,1408,1411,1413,1415,1418,1421,1425],{"class":1100,"line":1398},19,[1098,1400,1401],{"class":1115},"        token ",[1098,1403,1229],{"class":1133},[1098,1405,1363],{"class":1115},[1098,1407,1148],{"class":1133},[1098,1409,1410],{"class":1232},"split",[1098,1412,1255],{"class":1133},[1098,1414,1333],{"class":1332},[1098,1416,1417],{"class":1332}," '",[1098,1419,1420],{"class":1133},")[",[1098,1422,1424],{"class":1423},"s7CZa","1",[1098,1426,1427],{"class":1133},"]\n",[1098,1429,1431],{"class":1100,"line":1430},20,[1098,1432,1395],{"class":1115},[1098,1434,1436,1439],{"class":1100,"line":1435},21,[1098,1437,1438],{"class":1111},"        try",[1098,1440,1441],{"class":1133},":\n",[1098,1443,1445,1448,1450,1453,1455,1458],{"class":1100,"line":1444},22,[1098,1446,1447],{"class":1115},"            payload ",[1098,1449,1229],{"class":1133},[1098,1451,1452],{"class":1115}," jwt",[1098,1454,1148],{"class":1133},[1098,1456,1457],{"class":1232},"decode",[1098,1459,1460],{"class":1133},"(\n",[1098,1462,1464,1467,1469],{"class":1100,"line":1463},23,[1098,1465,1466],{"class":1232},"                token",[1098,1468,1134],{"class":1133},[1098,1470,1471],{"class":1232}," \n",[1098,1473,1475,1478,1480,1483,1485],{"class":1100,"line":1474},24,[1098,1476,1477],{"class":1232},"                settings",[1098,1479,1148],{"class":1133},[1098,1481,1482],{"class":1321},"JWT_SECRET_KEY",[1098,1484,1134],{"class":1133},[1098,1486,1471],{"class":1232},[1098,1488,1490,1494,1497,1500,1502,1505],{"class":1100,"line":1489},25,[1098,1491,1493],{"class":1492},"sqOPj","                algorithms",[1098,1495,1496],{"class":1133},"=[",[1098,1498,1499],{"class":1232},"settings",[1098,1501,1148],{"class":1133},[1098,1503,1504],{"class":1321},"JWT_ALGORITHM",[1098,1506,1427],{"class":1133},[1098,1508,1510],{"class":1100,"line":1509},26,[1098,1511,1512],{"class":1133},"            )\n",[1098,1514,1516],{"class":1100,"line":1515},27,[1098,1517,1518],{"class":1115},"            \n",[1098,1520,1522,1525,1527,1530,1532,1534,1536,1538,1541,1543],{"class":1100,"line":1521},28,[1098,1523,1524],{"class":1115},"            user_id ",[1098,1526,1229],{"class":1133},[1098,1528,1529],{"class":1115}," payload",[1098,1531,1148],{"class":1133},[1098,1533,1327],{"class":1232},[1098,1535,1255],{"class":1133},[1098,1537,1333],{"class":1332},[1098,1539,1540],{"class":1336},"user_id",[1098,1542,1333],{"class":1332},[1098,1544,1342],{"class":1133},[1098,1546,1548,1551,1553,1556],{"class":1100,"line":1547},29,[1098,1549,1550],{"class":1111},"            if",[1098,1552,1352],{"class":1351},[1098,1554,1555],{"class":1115}," user_id",[1098,1557,1441],{"class":1133},[1098,1559,1561,1564,1567,1569,1571,1574,1576],{"class":1100,"line":1560},30,[1098,1562,1563],{"class":1111},"                raise",[1098,1565,1566],{"class":1232}," AuthenticationFailed",[1098,1568,1255],{"class":1133},[1098,1570,1333],{"class":1332},[1098,1572,1573],{"class":1336},"Invalid token payload",[1098,1575,1333],{"class":1332},[1098,1577,1342],{"class":1133},[1098,1579,1581],{"class":1100,"line":1580},31,[1098,1582,1518],{"class":1115},[1098,1584,1586,1589,1591,1594,1596,1600,1602,1604,1606,1609,1611,1613],{"class":1100,"line":1585},32,[1098,1587,1588],{"class":1115},"            user ",[1098,1590,1229],{"class":1133},[1098,1592,1593],{"class":1115}," User",[1098,1595,1148],{"class":1133},[1098,1597,1599],{"class":1598},"sBPpx","objects",[1098,1601,1148],{"class":1133},[1098,1603,1327],{"class":1232},[1098,1605,1255],{"class":1133},[1098,1607,1608],{"class":1492},"id",[1098,1610,1229],{"class":1133},[1098,1612,1540],{"class":1232},[1098,1614,1342],{"class":1133},[1098,1616,1618,1620,1622,1625,1627,1630],{"class":1100,"line":1617},33,[1098,1619,1550],{"class":1111},[1098,1621,1352],{"class":1351},[1098,1623,1624],{"class":1115}," user",[1098,1626,1148],{"class":1133},[1098,1628,1629],{"class":1598},"is_active",[1098,1631,1441],{"class":1133},[1098,1633,1635,1637,1639,1641,1643,1646,1648],{"class":1100,"line":1634},34,[1098,1636,1563],{"class":1111},[1098,1638,1566],{"class":1232},[1098,1640,1255],{"class":1133},[1098,1642,1333],{"class":1332},[1098,1644,1645],{"class":1336},"User account is disabled",[1098,1647,1333],{"class":1332},[1098,1649,1342],{"class":1133},[1098,1651,1653],{"class":1100,"line":1652},35,[1098,1654,1518],{"class":1115},[1098,1656,1658,1660,1663,1666,1668,1671],{"class":1100,"line":1657},36,[1098,1659,1385],{"class":1111},[1098,1661,1662],{"class":1133}," (",[1098,1664,1665],{"class":1115},"user",[1098,1667,1134],{"class":1133},[1098,1669,1670],{"class":1115}," token",[1098,1672,1342],{"class":1133},[1098,1674,1676],{"class":1100,"line":1675},37,[1098,1677,1518],{"class":1115},[1098,1679,1681,1684,1686,1688,1691],{"class":1100,"line":1680},38,[1098,1682,1683],{"class":1111},"        except",[1098,1685,1452],{"class":1115},[1098,1687,1148],{"class":1133},[1098,1689,1690],{"class":1598},"ExpiredSignatureError",[1098,1692,1441],{"class":1133},[1098,1694,1696,1699,1701,1703,1705,1708,1710],{"class":1100,"line":1695},39,[1098,1697,1698],{"class":1111},"            raise",[1098,1700,1566],{"class":1232},[1098,1702,1255],{"class":1133},[1098,1704,1333],{"class":1332},[1098,1706,1707],{"class":1336},"Token has expired",[1098,1709,1333],{"class":1332},[1098,1711,1342],{"class":1133},[1098,1713,1715,1717,1719,1721,1724],{"class":1100,"line":1714},40,[1098,1716,1683],{"class":1111},[1098,1718,1452],{"class":1115},[1098,1720,1148],{"class":1133},[1098,1722,1723],{"class":1598},"InvalidTokenError",[1098,1725,1441],{"class":1133},[1098,1727,1729,1731,1733,1735,1737,1740,1742],{"class":1100,"line":1728},41,[1098,1730,1698],{"class":1111},[1098,1732,1566],{"class":1232},[1098,1734,1255],{"class":1133},[1098,1736,1333],{"class":1332},[1098,1738,1739],{"class":1336},"Invalid token",[1098,1741,1333],{"class":1332},[1098,1743,1342],{"class":1133},[1098,1745,1747,1749,1751,1753,1756],{"class":1100,"line":1746},42,[1098,1748,1683],{"class":1111},[1098,1750,1593],{"class":1115},[1098,1752,1148],{"class":1133},[1098,1754,1755],{"class":1598},"DoesNotExist",[1098,1757,1441],{"class":1133},[1098,1759,1761,1763,1765,1767,1769,1772,1774],{"class":1100,"line":1760},43,[1098,1762,1698],{"class":1111},[1098,1764,1566],{"class":1232},[1098,1766,1255],{"class":1133},[1098,1768,1333],{"class":1332},[1098,1770,1771],{"class":1336},"User not found",[1098,1773,1333],{"class":1332},[1098,1775,1342],{"class":1133},[1098,1777,1779],{"class":1100,"line":1778},44,[1098,1780,1220],{"emptyLinePlaceholder":1219},[1098,1782,1784,1786,1789],{"class":1100,"line":1783},45,[1098,1785,1248],{"class":1247},[1098,1787,1788],{"class":1251}," JWTTokenGenerator",[1098,1790,1441],{"class":1133},[1098,1792,1794,1796,1799],{"class":1100,"line":1793},46,[1098,1795,1269],{"class":1268},[1098,1797,1798],{"class":1272},"Generate and validate JWT tokens",[1098,1800,1276],{"class":1268},[1098,1802,1804],{"class":1100,"line":1803},47,[1098,1805,1282],{"class":1115},[1098,1807,1809,1812],{"class":1100,"line":1808},48,[1098,1810,1811],{"class":1133},"    @",[1098,1813,1815],{"class":1814},"sa2tF","staticmethod\n",[1098,1817,1819,1821,1824,1826,1828],{"class":1100,"line":1818},49,[1098,1820,1288],{"class":1247},[1098,1822,1823],{"class":1291}," generate_access_token",[1098,1825,1255],{"class":1133},[1098,1827,1665],{"class":1303},[1098,1829,1262],{"class":1133},[1098,1831,1833,1836,1839],{"class":1100,"line":1832},50,[1098,1834,1835],{"class":1268},"        \"\"\"",[1098,1837,1838],{"class":1272},"Generate access token",[1098,1840,1276],{"class":1268},[1098,1842,1844,1847,1849],{"class":1100,"line":1843},51,[1098,1845,1846],{"class":1115},"        payload ",[1098,1848,1229],{"class":1133},[1098,1850,1851],{"class":1133}," {\n",[1098,1853,1855,1858,1860,1862,1865,1867,1869,1871],{"class":1100,"line":1854},52,[1098,1856,1857],{"class":1332},"            '",[1098,1859,1540],{"class":1336},[1098,1861,1333],{"class":1332},[1098,1863,1864],{"class":1133},":",[1098,1866,1624],{"class":1115},[1098,1868,1148],{"class":1133},[1098,1870,1608],{"class":1598},[1098,1872,1873],{"class":1133},",\n",[1098,1875,1877,1879,1882,1884,1886,1888,1890,1892],{"class":1100,"line":1876},53,[1098,1878,1857],{"class":1332},[1098,1880,1881],{"class":1336},"username",[1098,1883,1333],{"class":1332},[1098,1885,1864],{"class":1133},[1098,1887,1624],{"class":1115},[1098,1889,1148],{"class":1133},[1098,1891,1881],{"class":1598},[1098,1893,1873],{"class":1133},[1098,1895,1897,1899,1902,1904,1906,1908,1910,1912],{"class":1100,"line":1896},54,[1098,1898,1857],{"class":1332},[1098,1900,1901],{"class":1336},"email",[1098,1903,1333],{"class":1332},[1098,1905,1864],{"class":1133},[1098,1907,1624],{"class":1115},[1098,1909,1148],{"class":1133},[1098,1911,1901],{"class":1598},[1098,1913,1873],{"class":1133},[1098,1915,1917,1919,1922,1924,1926,1928,1930,1933,1936,1939,1942,1944,1947,1949,1951,1953,1956],{"class":1100,"line":1916},55,[1098,1918,1857],{"class":1332},[1098,1920,1921],{"class":1336},"exp",[1098,1923,1333],{"class":1332},[1098,1925,1864],{"class":1133},[1098,1927,1130],{"class":1115},[1098,1929,1148],{"class":1133},[1098,1931,1932],{"class":1232},"utcnow",[1098,1934,1935],{"class":1133},"()",[1098,1937,1938],{"class":1351}," +",[1098,1940,1941],{"class":1232}," timedelta",[1098,1943,1255],{"class":1133},[1098,1945,1946],{"class":1492},"minutes",[1098,1948,1229],{"class":1133},[1098,1950,1499],{"class":1232},[1098,1952,1148],{"class":1133},[1098,1954,1955],{"class":1321},"JWT_ACCESS_TOKEN_LIFETIME",[1098,1957,1958],{"class":1133},"),\n",[1098,1960,1962,1964,1967,1969,1971,1973,1975,1977],{"class":1100,"line":1961},56,[1098,1963,1857],{"class":1332},[1098,1965,1966],{"class":1336},"iat",[1098,1968,1333],{"class":1332},[1098,1970,1864],{"class":1133},[1098,1972,1130],{"class":1115},[1098,1974,1148],{"class":1133},[1098,1976,1932],{"class":1232},[1098,1978,1979],{"class":1133},"(),\n",[1098,1981,1983,1985,1988,1990,1992,1994,1997],{"class":1100,"line":1982},57,[1098,1984,1857],{"class":1332},[1098,1986,1987],{"class":1336},"type",[1098,1989,1333],{"class":1332},[1098,1991,1864],{"class":1133},[1098,1993,1417],{"class":1332},[1098,1995,1996],{"class":1336},"access",[1098,1998,1999],{"class":1332},"'\n",[1098,2001,2003],{"class":1100,"line":2002},58,[1098,2004,2005],{"class":1133},"        }\n",[1098,2007,2009],{"class":1100,"line":2008},59,[1098,2010,1395],{"class":1115},[1098,2012,2014,2017,2019,2021,2024],{"class":1100,"line":2013},60,[1098,2015,2016],{"class":1111},"        return",[1098,2018,1452],{"class":1115},[1098,2020,1148],{"class":1133},[1098,2022,2023],{"class":1232},"encode",[1098,2025,1460],{"class":1133},[1098,2027,2029,2032,2034],{"class":1100,"line":2028},61,[1098,2030,2031],{"class":1232},"            payload",[1098,2033,1134],{"class":1133},[1098,2035,1471],{"class":1232},[1098,2037,2039,2042,2044,2046,2048],{"class":1100,"line":2038},62,[1098,2040,2041],{"class":1232},"            settings",[1098,2043,1148],{"class":1133},[1098,2045,1482],{"class":1321},[1098,2047,1134],{"class":1133},[1098,2049,1471],{"class":1232},[1098,2051,2053,2056,2058,2060,2062],{"class":1100,"line":2052},63,[1098,2054,2055],{"class":1492},"            algorithm",[1098,2057,1229],{"class":1133},[1098,2059,1499],{"class":1232},[1098,2061,1148],{"class":1133},[1098,2063,2064],{"class":1321},"JWT_ALGORITHM\n",[1098,2066,2068],{"class":1100,"line":2067},64,[1098,2069,2070],{"class":1133},"        )\n",[1098,2072,2074],{"class":1100,"line":2073},65,[1098,2075,1282],{"class":1115},[1098,2077,2079,2081],{"class":1100,"line":2078},66,[1098,2080,1811],{"class":1133},[1098,2082,1815],{"class":1814},[1098,2084,2086,2088,2091,2093,2095],{"class":1100,"line":2085},67,[1098,2087,1288],{"class":1247},[1098,2089,2090],{"class":1291}," generate_refresh_token",[1098,2092,1255],{"class":1133},[1098,2094,1665],{"class":1303},[1098,2096,1262],{"class":1133},[1098,2098,2100,2102,2105],{"class":1100,"line":2099},68,[1098,2101,1835],{"class":1268},[1098,2103,2104],{"class":1272},"Generate refresh token",[1098,2106,1276],{"class":1268},[1098,2108,2110,2112,2114],{"class":1100,"line":2109},69,[1098,2111,1846],{"class":1115},[1098,2113,1229],{"class":1133},[1098,2115,1851],{"class":1133},[1098,2117,2119,2121,2123,2125,2127,2129,2131,2133],{"class":1100,"line":2118},70,[1098,2120,1857],{"class":1332},[1098,2122,1540],{"class":1336},[1098,2124,1333],{"class":1332},[1098,2126,1864],{"class":1133},[1098,2128,1624],{"class":1115},[1098,2130,1148],{"class":1133},[1098,2132,1608],{"class":1598},[1098,2134,1873],{"class":1133},[1098,2136,2138,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2163,2165,2167,2169,2172],{"class":1100,"line":2137},71,[1098,2139,1857],{"class":1332},[1098,2141,1921],{"class":1336},[1098,2143,1333],{"class":1332},[1098,2145,1864],{"class":1133},[1098,2147,1130],{"class":1115},[1098,2149,1148],{"class":1133},[1098,2151,1932],{"class":1232},[1098,2153,1935],{"class":1133},[1098,2155,1938],{"class":1351},[1098,2157,1941],{"class":1232},[1098,2159,1255],{"class":1133},[1098,2161,2162],{"class":1492},"days",[1098,2164,1229],{"class":1133},[1098,2166,1499],{"class":1232},[1098,2168,1148],{"class":1133},[1098,2170,2171],{"class":1321},"JWT_REFRESH_TOKEN_LIFETIME",[1098,2173,1958],{"class":1133},[1098,2175,2177,2179,2181,2183,2185,2187,2189,2191],{"class":1100,"line":2176},72,[1098,2178,1857],{"class":1332},[1098,2180,1966],{"class":1336},[1098,2182,1333],{"class":1332},[1098,2184,1864],{"class":1133},[1098,2186,1130],{"class":1115},[1098,2188,1148],{"class":1133},[1098,2190,1932],{"class":1232},[1098,2192,1979],{"class":1133},[1098,2194,2196,2198,2200,2202,2204,2206,2209],{"class":1100,"line":2195},73,[1098,2197,1857],{"class":1332},[1098,2199,1987],{"class":1336},[1098,2201,1333],{"class":1332},[1098,2203,1864],{"class":1133},[1098,2205,1417],{"class":1332},[1098,2207,2208],{"class":1336},"refresh",[1098,2210,1999],{"class":1332},[1098,2212,2214],{"class":1100,"line":2213},74,[1098,2215,2005],{"class":1133},[1098,2217,2219],{"class":1100,"line":2218},75,[1098,2220,1395],{"class":1115},[1098,2222,2224,2226,2228,2230,2232],{"class":1100,"line":2223},76,[1098,2225,2016],{"class":1111},[1098,2227,1452],{"class":1115},[1098,2229,1148],{"class":1133},[1098,2231,2023],{"class":1232},[1098,2233,1460],{"class":1133},[1098,2235,2237,2239,2241],{"class":1100,"line":2236},77,[1098,2238,2031],{"class":1232},[1098,2240,1134],{"class":1133},[1098,2242,1471],{"class":1232},[1098,2244,2246,2248,2250,2252,2254],{"class":1100,"line":2245},78,[1098,2247,2041],{"class":1232},[1098,2249,1148],{"class":1133},[1098,2251,1482],{"class":1321},[1098,2253,1134],{"class":1133},[1098,2255,1471],{"class":1232},[1098,2257,2259,2261,2263,2265,2267],{"class":1100,"line":2258},79,[1098,2260,2055],{"class":1492},[1098,2262,1229],{"class":1133},[1098,2264,1499],{"class":1232},[1098,2266,1148],{"class":1133},[1098,2268,2064],{"class":1321},[1098,2270,2272],{"class":1100,"line":2271},80,[1098,2273,2070],{"class":1133},[1098,2275,2277],{"class":1100,"line":2276},81,[1098,2278,1282],{"class":1115},[1098,2280,2282,2284],{"class":1100,"line":2281},82,[1098,2283,1811],{"class":1133},[1098,2285,1815],{"class":1814},[1098,2287,2289,2291,2294,2296,2299,2301,2304,2306,2308,2310,2312],{"class":1100,"line":2288},83,[1098,2290,1288],{"class":1247},[1098,2292,2293],{"class":1291}," verify_token",[1098,2295,1255],{"class":1133},[1098,2297,2298],{"class":1303},"token",[1098,2300,1134],{"class":1133},[1098,2302,2303],{"class":1303}," token_type",[1098,2305,1229],{"class":1351},[1098,2307,1333],{"class":1332},[1098,2309,1996],{"class":1336},[1098,2311,1333],{"class":1332},[1098,2313,1262],{"class":1133},[1098,2315,2317,2319,2322],{"class":1100,"line":2316},84,[1098,2318,1835],{"class":1268},[1098,2320,2321],{"class":1272},"Verify token and return payload",[1098,2323,1276],{"class":1268},[1098,2325,2327,2329],{"class":1100,"line":2326},85,[1098,2328,1438],{"class":1111},[1098,2330,1441],{"class":1133},[1098,2332,2334,2336,2338,2340,2342,2344],{"class":1100,"line":2333},86,[1098,2335,1447],{"class":1115},[1098,2337,1229],{"class":1133},[1098,2339,1452],{"class":1115},[1098,2341,1148],{"class":1133},[1098,2343,1457],{"class":1232},[1098,2345,1460],{"class":1133},[1098,2347,2349,2351,2353],{"class":1100,"line":2348},87,[1098,2350,1466],{"class":1232},[1098,2352,1134],{"class":1133},[1098,2354,1471],{"class":1232},[1098,2356,2358,2360,2362,2364,2366],{"class":1100,"line":2357},88,[1098,2359,1477],{"class":1232},[1098,2361,1148],{"class":1133},[1098,2363,1482],{"class":1321},[1098,2365,1134],{"class":1133},[1098,2367,1471],{"class":1232},[1098,2369,2371,2373,2375,2377,2379,2381],{"class":1100,"line":2370},89,[1098,2372,1493],{"class":1492},[1098,2374,1496],{"class":1133},[1098,2376,1499],{"class":1232},[1098,2378,1148],{"class":1133},[1098,2380,1504],{"class":1321},[1098,2382,1427],{"class":1133},[1098,2384,2386],{"class":1100,"line":2385},90,[1098,2387,1512],{"class":1133},[1098,2389,2391],{"class":1100,"line":2390},91,[1098,2392,1518],{"class":1115},[1098,2394,2396,2398,2400,2402,2404,2406,2408,2410,2412,2415,2418,2420],{"class":1100,"line":2395},92,[1098,2397,1550],{"class":1111},[1098,2399,1529],{"class":1115},[1098,2401,1148],{"class":1133},[1098,2403,1327],{"class":1232},[1098,2405,1255],{"class":1133},[1098,2407,1333],{"class":1332},[1098,2409,1987],{"class":1336},[1098,2411,1333],{"class":1332},[1098,2413,2414],{"class":1133},")",[1098,2416,2417],{"class":1351}," !=",[1098,2419,2303],{"class":1115},[1098,2421,1441],{"class":1133},[1098,2423,2425,2427,2429,2431,2433,2435,2437,2440,2442],{"class":1100,"line":2424},93,[1098,2426,1563],{"class":1111},[1098,2428,1452],{"class":1115},[1098,2430,1148],{"class":1133},[1098,2432,1723],{"class":1232},[1098,2434,1255],{"class":1133},[1098,2436,1333],{"class":1332},[1098,2438,2439],{"class":1336},"Invalid token type",[1098,2441,1333],{"class":1332},[1098,2443,1342],{"class":1133},[1098,2445,2447],{"class":1100,"line":2446},94,[1098,2448,1518],{"class":1115},[1098,2450,2452,2454],{"class":1100,"line":2451},95,[1098,2453,1385],{"class":1111},[1098,2455,2456],{"class":1115}," payload\n",[1098,2458,2460],{"class":1100,"line":2459},96,[1098,2461,1518],{"class":1115},[1098,2463,2465,2467,2469,2471,2473],{"class":1100,"line":2464},97,[1098,2466,1683],{"class":1111},[1098,2468,1452],{"class":1115},[1098,2470,1148],{"class":1133},[1098,2472,1690],{"class":1598},[1098,2474,1441],{"class":1133},[1098,2476,2478,2480,2482,2484,2486,2488,2490],{"class":1100,"line":2477},98,[1098,2479,1698],{"class":1111},[1098,2481,1566],{"class":1232},[1098,2483,1255],{"class":1133},[1098,2485,1333],{"class":1332},[1098,2487,1707],{"class":1336},[1098,2489,1333],{"class":1332},[1098,2491,1342],{"class":1133},[1098,2493,2495,2497,2499,2501,2503],{"class":1100,"line":2494},99,[1098,2496,1683],{"class":1111},[1098,2498,1452],{"class":1115},[1098,2500,1148],{"class":1133},[1098,2502,1723],{"class":1598},[1098,2504,1441],{"class":1133},[1098,2506,2508,2510,2512,2514,2516,2518,2520],{"class":1100,"line":2507},100,[1098,2509,1698],{"class":1111},[1098,2511,1566],{"class":1232},[1098,2513,1255],{"class":1133},[1098,2515,1333],{"class":1332},[1098,2517,1739],{"class":1336},[1098,2519,1333],{"class":1332},[1098,2521,1342],{"class":1133},[1098,2523,2525],{"class":1100,"line":2524},101,[1098,2526,1220],{"emptyLinePlaceholder":1219},[1098,2528,2530],{"class":1100,"line":2529},102,[1098,2531,2532],{"class":1104},"# views.py\n",[1098,2534,2536,2538,2540,2542,2545,2547,2550,2552],{"class":1100,"line":2535},103,[1098,2537,1122],{"class":1111},[1098,2539,1186],{"class":1115},[1098,2541,1148],{"class":1133},[1098,2543,2544],{"class":1115},"decorators ",[1098,2546,1112],{"class":1111},[1098,2548,2549],{"class":1115}," api_view",[1098,2551,1134],{"class":1133},[1098,2553,2554],{"class":1115}," permission_classes\n",[1098,2556,2558,2560,2562,2564,2567,2569],{"class":1100,"line":2557},104,[1098,2559,1122],{"class":1111},[1098,2561,1186],{"class":1115},[1098,2563,1148],{"class":1133},[1098,2565,2566],{"class":1115},"permissions ",[1098,2568,1112],{"class":1111},[1098,2570,2571],{"class":1115}," AllowAny\n",[1098,2573,2575,2577,2579,2581,2584,2586],{"class":1100,"line":2574},105,[1098,2576,1122],{"class":1111},[1098,2578,1186],{"class":1115},[1098,2580,1148],{"class":1133},[1098,2582,2583],{"class":1115},"response ",[1098,2585,1112],{"class":1111},[1098,2587,2588],{"class":1115}," Response\n",[1098,2590,2592,2594,2597,2599],{"class":1100,"line":2591},106,[1098,2593,1122],{"class":1111},[1098,2595,2596],{"class":1115}," rest_framework ",[1098,2598,1112],{"class":1111},[1098,2600,2601],{"class":1115}," status\n",[1098,2603,2605,2607,2609,2611,2613,2615,2617,2619],{"class":1100,"line":2604},107,[1098,2606,1122],{"class":1111},[1098,2608,1145],{"class":1115},[1098,2610,1148],{"class":1133},[1098,2612,1168],{"class":1115},[1098,2614,1148],{"class":1133},[1098,2616,1173],{"class":1115},[1098,2618,1112],{"class":1111},[1098,2620,2621],{"class":1115}," authenticate\n",[1098,2623,2625],{"class":1100,"line":2624},108,[1098,2626,1220],{"emptyLinePlaceholder":1219},[1098,2628,2630,2633,2636,2639,2641,2644,2646],{"class":1100,"line":2629},109,[1098,2631,2632],{"class":1133},"@",[1098,2634,2635],{"class":1291},"api_view",[1098,2637,2638],{"class":1133},"([",[1098,2640,1333],{"class":1332},[1098,2642,2643],{"class":1336},"POST",[1098,2645,1333],{"class":1332},[1098,2647,2648],{"class":1133},"])\n",[1098,2650,2652,2654,2657,2659,2662],{"class":1100,"line":2651},110,[1098,2653,2632],{"class":1133},[1098,2655,2656],{"class":1291},"permission_classes",[1098,2658,2638],{"class":1133},[1098,2660,2661],{"class":1232},"AllowAny",[1098,2663,2648],{"class":1133},[1098,2665,2667,2670,2673,2675,2678],{"class":1100,"line":2666},111,[1098,2668,2669],{"class":1247},"def",[1098,2671,2672],{"class":1291}," login",[1098,2674,1255],{"class":1133},[1098,2676,2677],{"class":1303},"request",[1098,2679,1262],{"class":1133},[1098,2681,2683,2685,2688],{"class":1100,"line":2682},112,[1098,2684,1269],{"class":1268},[1098,2686,2687],{"class":1272},"User login endpoint",[1098,2689,1276],{"class":1268},[1098,2691,2693,2696,2698,2700,2702,2705,2707,2709,2711,2713,2715,2717],{"class":1100,"line":2692},113,[1098,2694,2695],{"class":1115},"    username ",[1098,2697,1229],{"class":1133},[1098,2699,1304],{"class":1115},[1098,2701,1148],{"class":1133},[1098,2703,2704],{"class":1598},"data",[1098,2706,1148],{"class":1133},[1098,2708,1327],{"class":1232},[1098,2710,1255],{"class":1133},[1098,2712,1333],{"class":1332},[1098,2714,1881],{"class":1336},[1098,2716,1333],{"class":1332},[1098,2718,1342],{"class":1133},[1098,2720,2722,2725,2727,2729,2731,2733,2735,2737,2739,2741,2744,2746],{"class":1100,"line":2721},114,[1098,2723,2724],{"class":1115},"    password ",[1098,2726,1229],{"class":1133},[1098,2728,1304],{"class":1115},[1098,2730,1148],{"class":1133},[1098,2732,2704],{"class":1598},[1098,2734,1148],{"class":1133},[1098,2736,1327],{"class":1232},[1098,2738,1255],{"class":1133},[1098,2740,1333],{"class":1332},[1098,2742,2743],{"class":1336},"password",[1098,2745,1333],{"class":1332},[1098,2747,1342],{"class":1133},[1098,2749,2751],{"class":1100,"line":2750},115,[1098,2752,1282],{"class":1115},[1098,2754,2756,2759,2761,2764,2766,2768,2771],{"class":1100,"line":2755},116,[1098,2757,2758],{"class":1111},"    if",[1098,2760,1352],{"class":1351},[1098,2762,2763],{"class":1115}," username ",[1098,2765,1358],{"class":1351},[1098,2767,1352],{"class":1351},[1098,2769,2770],{"class":1115}," password",[1098,2772,1441],{"class":1133},[1098,2774,2776,2778,2781],{"class":1100,"line":2775},117,[1098,2777,2016],{"class":1111},[1098,2779,2780],{"class":1232}," Response",[1098,2782,1460],{"class":1133},[1098,2784,2786,2789,2791,2794,2796,2798,2800,2803,2805,2808],{"class":1100,"line":2785},118,[1098,2787,2788],{"class":1133},"            {",[1098,2790,1333],{"class":1332},[1098,2792,2793],{"class":1336},"error",[1098,2795,1333],{"class":1332},[1098,2797,1864],{"class":1133},[1098,2799,1417],{"class":1332},[1098,2801,2802],{"class":1336},"Username and password required",[1098,2804,1333],{"class":1332},[1098,2806,2807],{"class":1133},"},",[1098,2809,1471],{"class":1232},[1098,2811,2813,2816,2818,2821,2823],{"class":1100,"line":2812},119,[1098,2814,2815],{"class":1492},"            status",[1098,2817,1229],{"class":1133},[1098,2819,2820],{"class":1232},"status",[1098,2822,1148],{"class":1133},[1098,2824,2825],{"class":1321},"HTTP_400_BAD_REQUEST\n",[1098,2827,2829],{"class":1100,"line":2828},120,[1098,2830,2070],{"class":1133},[1098,2832,2834],{"class":1100,"line":2833},121,[1098,2835,1282],{"class":1115},[1098,2837,2839,2842,2844,2846,2848,2850,2852,2854,2856,2858,2860,2862],{"class":1100,"line":2838},122,[1098,2840,2841],{"class":1115},"    user ",[1098,2843,1229],{"class":1133},[1098,2845,1292],{"class":1232},[1098,2847,1255],{"class":1133},[1098,2849,1881],{"class":1492},[1098,2851,1229],{"class":1133},[1098,2853,1881],{"class":1232},[1098,2855,1134],{"class":1133},[1098,2857,2770],{"class":1492},[1098,2859,1229],{"class":1133},[1098,2861,2743],{"class":1232},[1098,2863,1342],{"class":1133},[1098,2865,2867,2869,2871,2873],{"class":1100,"line":2866},123,[1098,2868,2758],{"class":1111},[1098,2870,1352],{"class":1351},[1098,2872,1624],{"class":1115},[1098,2874,1441],{"class":1133},[1098,2876,2878,2880,2882],{"class":1100,"line":2877},124,[1098,2879,2016],{"class":1111},[1098,2881,2780],{"class":1232},[1098,2883,1460],{"class":1133},[1098,2885,2887,2889,2891,2893,2895,2897,2899,2902,2904,2906],{"class":1100,"line":2886},125,[1098,2888,2788],{"class":1133},[1098,2890,1333],{"class":1332},[1098,2892,2793],{"class":1336},[1098,2894,1333],{"class":1332},[1098,2896,1864],{"class":1133},[1098,2898,1417],{"class":1332},[1098,2900,2901],{"class":1336},"Invalid credentials",[1098,2903,1333],{"class":1332},[1098,2905,2807],{"class":1133},[1098,2907,1471],{"class":1232},[1098,2909,2911,2913,2915,2917,2919],{"class":1100,"line":2910},126,[1098,2912,2815],{"class":1492},[1098,2914,1229],{"class":1133},[1098,2916,2820],{"class":1232},[1098,2918,1148],{"class":1133},[1098,2920,2921],{"class":1321},"HTTP_401_UNAUTHORIZED\n",[1098,2923,2925],{"class":1100,"line":2924},127,[1098,2926,2070],{"class":1133},[1098,2928,2930],{"class":1100,"line":2929},128,[1098,2931,1282],{"class":1115},[1098,2933,2935,2938,2940,2942,2944,2947,2949,2951],{"class":1100,"line":2934},129,[1098,2936,2937],{"class":1115},"    access_token ",[1098,2939,1229],{"class":1133},[1098,2941,1788],{"class":1115},[1098,2943,1148],{"class":1133},[1098,2945,2946],{"class":1232},"generate_access_token",[1098,2948,1255],{"class":1133},[1098,2950,1665],{"class":1232},[1098,2952,1342],{"class":1133},[1098,2954,2956,2959,2961,2963,2965,2968,2970,2972],{"class":1100,"line":2955},130,[1098,2957,2958],{"class":1115},"    refresh_token ",[1098,2960,1229],{"class":1133},[1098,2962,1788],{"class":1115},[1098,2964,1148],{"class":1133},[1098,2966,2967],{"class":1232},"generate_refresh_token",[1098,2969,1255],{"class":1133},[1098,2971,1665],{"class":1232},[1098,2973,1342],{"class":1133},[1098,2975,2977],{"class":1100,"line":2976},131,[1098,2978,1282],{"class":1115},[1098,2980,2982,2985,2987],{"class":1100,"line":2981},132,[1098,2983,2984],{"class":1111},"    return",[1098,2986,2780],{"class":1232},[1098,2988,2989],{"class":1133},"({\n",[1098,2991,2993,2996,2999,3001,3003,3006],{"class":1100,"line":2992},133,[1098,2994,2995],{"class":1332},"        '",[1098,2997,2998],{"class":1336},"access_token",[1098,3000,1333],{"class":1332},[1098,3002,1864],{"class":1133},[1098,3004,3005],{"class":1232}," access_token",[1098,3007,1873],{"class":1133},[1098,3009,3011,3013,3016,3018,3020,3023],{"class":1100,"line":3010},134,[1098,3012,2995],{"class":1332},[1098,3014,3015],{"class":1336},"refresh_token",[1098,3017,1333],{"class":1332},[1098,3019,1864],{"class":1133},[1098,3021,3022],{"class":1232}," refresh_token",[1098,3024,1873],{"class":1133},[1098,3026,3028,3030,3032,3034,3036],{"class":1100,"line":3027},135,[1098,3029,2995],{"class":1332},[1098,3031,1665],{"class":1336},[1098,3033,1333],{"class":1332},[1098,3035,1864],{"class":1133},[1098,3037,1851],{"class":1133},[1098,3039,3041,3043,3045,3047,3049,3051,3053,3055],{"class":1100,"line":3040},136,[1098,3042,1857],{"class":1332},[1098,3044,1608],{"class":1336},[1098,3046,1333],{"class":1332},[1098,3048,1864],{"class":1133},[1098,3050,1624],{"class":1232},[1098,3052,1148],{"class":1133},[1098,3054,1608],{"class":1598},[1098,3056,1873],{"class":1133},[1098,3058,3060,3062,3064,3066,3068,3070,3072,3074],{"class":1100,"line":3059},137,[1098,3061,1857],{"class":1332},[1098,3063,1881],{"class":1336},[1098,3065,1333],{"class":1332},[1098,3067,1864],{"class":1133},[1098,3069,1624],{"class":1232},[1098,3071,1148],{"class":1133},[1098,3073,1881],{"class":1598},[1098,3075,1873],{"class":1133},[1098,3077,3079,3081,3083,3085,3087,3089,3091],{"class":1100,"line":3078},138,[1098,3080,1857],{"class":1332},[1098,3082,1901],{"class":1336},[1098,3084,1333],{"class":1332},[1098,3086,1864],{"class":1133},[1098,3088,1624],{"class":1232},[1098,3090,1148],{"class":1133},[1098,3092,3093],{"class":1598},"email\n",[1098,3095,3097],{"class":1100,"line":3096},139,[1098,3098,2005],{"class":1133},[1098,3100,3102],{"class":1100,"line":3101},140,[1098,3103,3104],{"class":1133},"    })\n",[1098,3106,3108],{"class":1100,"line":3107},141,[1098,3109,1220],{"emptyLinePlaceholder":1219},[1098,3111,3113,3115,3117,3119,3121,3123,3125],{"class":1100,"line":3112},142,[1098,3114,2632],{"class":1133},[1098,3116,2635],{"class":1291},[1098,3118,2638],{"class":1133},[1098,3120,1333],{"class":1332},[1098,3122,2643],{"class":1336},[1098,3124,1333],{"class":1332},[1098,3126,2648],{"class":1133},[1098,3128,3130,3132,3134,3136,3138],{"class":1100,"line":3129},143,[1098,3131,2632],{"class":1133},[1098,3133,2656],{"class":1291},[1098,3135,2638],{"class":1133},[1098,3137,2661],{"class":1232},[1098,3139,2648],{"class":1133},[1098,3141,3143,3145,3147,3149,3151],{"class":1100,"line":3142},144,[1098,3144,2669],{"class":1247},[1098,3146,3022],{"class":1291},[1098,3148,1255],{"class":1133},[1098,3150,2677],{"class":1303},[1098,3152,1262],{"class":1133},[1098,3154,3156,3158,3161],{"class":1100,"line":3155},145,[1098,3157,1269],{"class":1268},[1098,3159,3160],{"class":1272},"Refresh access token",[1098,3162,1276],{"class":1268},[1098,3164,3166,3168,3170,3172,3174,3176,3178,3180,3182,3184,3186,3188],{"class":1100,"line":3165},146,[1098,3167,2958],{"class":1115},[1098,3169,1229],{"class":1133},[1098,3171,1304],{"class":1115},[1098,3173,1148],{"class":1133},[1098,3175,2704],{"class":1598},[1098,3177,1148],{"class":1133},[1098,3179,1327],{"class":1232},[1098,3181,1255],{"class":1133},[1098,3183,1333],{"class":1332},[1098,3185,3015],{"class":1336},[1098,3187,1333],{"class":1332},[1098,3189,1342],{"class":1133},[1098,3191,3193],{"class":1100,"line":3192},147,[1098,3194,1282],{"class":1115},[1098,3196,3198,3200,3202,3204],{"class":1100,"line":3197},148,[1098,3199,2758],{"class":1111},[1098,3201,1352],{"class":1351},[1098,3203,3022],{"class":1115},[1098,3205,1441],{"class":1133},[1098,3207,3209,3211,3213],{"class":1100,"line":3208},149,[1098,3210,2016],{"class":1111},[1098,3212,2780],{"class":1232},[1098,3214,1460],{"class":1133},[1098,3216,3218,3220,3222,3224,3226,3228,3230,3233,3235,3237],{"class":1100,"line":3217},150,[1098,3219,2788],{"class":1133},[1098,3221,1333],{"class":1332},[1098,3223,2793],{"class":1336},[1098,3225,1333],{"class":1332},[1098,3227,1864],{"class":1133},[1098,3229,1417],{"class":1332},[1098,3231,3232],{"class":1336},"Refresh token required",[1098,3234,1333],{"class":1332},[1098,3236,2807],{"class":1133},[1098,3238,1471],{"class":1232},[1098,3240,3242,3244,3246,3248,3250],{"class":1100,"line":3241},151,[1098,3243,2815],{"class":1492},[1098,3245,1229],{"class":1133},[1098,3247,2820],{"class":1232},[1098,3249,1148],{"class":1133},[1098,3251,2825],{"class":1321},[1098,3253,3255],{"class":1100,"line":3254},152,[1098,3256,2070],{"class":1133},[1098,3258,3260],{"class":1100,"line":3259},153,[1098,3261,1282],{"class":1115},[1098,3263,3265,3268],{"class":1100,"line":3264},154,[1098,3266,3267],{"class":1111},"    try",[1098,3269,1441],{"class":1133},[1098,3271,3273,3275,3277,3279,3281,3284,3286,3288,3290,3292,3294,3296],{"class":1100,"line":3272},155,[1098,3274,1846],{"class":1115},[1098,3276,1229],{"class":1133},[1098,3278,1788],{"class":1115},[1098,3280,1148],{"class":1133},[1098,3282,3283],{"class":1232},"verify_token",[1098,3285,1255],{"class":1133},[1098,3287,3015],{"class":1232},[1098,3289,1134],{"class":1133},[1098,3291,1417],{"class":1332},[1098,3293,2208],{"class":1336},[1098,3295,1333],{"class":1332},[1098,3297,1342],{"class":1133},[1098,3299,3301,3304,3306,3308,3310,3312,3314,3316,3318,3320,3322,3325,3328,3330,3332,3334],{"class":1100,"line":3300},156,[1098,3302,3303],{"class":1115},"        user ",[1098,3305,1229],{"class":1133},[1098,3307,1593],{"class":1115},[1098,3309,1148],{"class":1133},[1098,3311,1599],{"class":1598},[1098,3313,1148],{"class":1133},[1098,3315,1327],{"class":1232},[1098,3317,1255],{"class":1133},[1098,3319,1608],{"class":1492},[1098,3321,1229],{"class":1133},[1098,3323,3324],{"class":1232},"payload",[1098,3326,3327],{"class":1133},"[",[1098,3329,1333],{"class":1332},[1098,3331,1540],{"class":1336},[1098,3333,1333],{"class":1332},[1098,3335,2648],{"class":1133},[1098,3337,3339],{"class":1100,"line":3338},157,[1098,3340,1395],{"class":1115},[1098,3342,3344,3347,3349,3351,3353,3355,3357,3359],{"class":1100,"line":3343},158,[1098,3345,3346],{"class":1115},"        new_access_token ",[1098,3348,1229],{"class":1133},[1098,3350,1788],{"class":1115},[1098,3352,1148],{"class":1133},[1098,3354,2946],{"class":1232},[1098,3356,1255],{"class":1133},[1098,3358,1665],{"class":1232},[1098,3360,1342],{"class":1133},[1098,3362,3364],{"class":1100,"line":3363},159,[1098,3365,1395],{"class":1115},[1098,3367,3369,3371,3373],{"class":1100,"line":3368},160,[1098,3370,2016],{"class":1111},[1098,3372,2780],{"class":1232},[1098,3374,2989],{"class":1133},[1098,3376,3378,3380,3382,3384,3386],{"class":1100,"line":3377},161,[1098,3379,1857],{"class":1332},[1098,3381,2998],{"class":1336},[1098,3383,1333],{"class":1332},[1098,3385,1864],{"class":1133},[1098,3387,3388],{"class":1232}," new_access_token\n",[1098,3390,3392],{"class":1100,"line":3391},162,[1098,3393,3394],{"class":1133},"        })\n",[1098,3396,3398],{"class":1100,"line":3397},163,[1098,3399,1395],{"class":1115},[1098,3401,3403,3406,3408,3411,3413,3415,3417,3419,3421,3424,3427],{"class":1100,"line":3402},164,[1098,3404,3405],{"class":1111},"    except",[1098,3407,1662],{"class":1133},[1098,3409,3410],{"class":1115},"AuthenticationFailed",[1098,3412,1134],{"class":1133},[1098,3414,1593],{"class":1115},[1098,3416,1148],{"class":1133},[1098,3418,1755],{"class":1598},[1098,3420,2414],{"class":1133},[1098,3422,3423],{"class":1111}," as",[1098,3425,3426],{"class":1115}," e",[1098,3428,1441],{"class":1133},[1098,3430,3432,3434,3436],{"class":1100,"line":3431},165,[1098,3433,2016],{"class":1111},[1098,3435,2780],{"class":1232},[1098,3437,1460],{"class":1133},[1098,3439,3441,3443,3445,3447,3449,3451,3454,3456,3459,3462],{"class":1100,"line":3440},166,[1098,3442,2788],{"class":1133},[1098,3444,1333],{"class":1332},[1098,3446,2793],{"class":1336},[1098,3448,1333],{"class":1332},[1098,3450,1864],{"class":1133},[1098,3452,3453],{"class":1814}," str",[1098,3455,1255],{"class":1133},[1098,3457,3458],{"class":1232},"e",[1098,3460,3461],{"class":1133},")},",[1098,3463,1471],{"class":1232},[1098,3465,3467,3469,3471,3473,3475],{"class":1100,"line":3466},167,[1098,3468,2815],{"class":1492},[1098,3470,1229],{"class":1133},[1098,3472,2820],{"class":1232},[1098,3474,1148],{"class":1133},[1098,3476,2921],{"class":1321},[1098,3478,3480],{"class":1100,"line":3479},168,[1098,3481,2070],{"class":1133},[1035,3483,3485],{"id":3484},"_2-oauth-20-integration","2. OAuth 2.0 Integration",[1088,3487,3489],{"className":1090,"code":3488,"language":1092,"meta":1093,"style":1093},"# oauth.py\nimport requests\nfrom django.conf import settings\nfrom rest_framework.authentication import BaseAuthentication\nfrom rest_framework.exceptions import AuthenticationFailed\n\nclass OAuth2Authentication(BaseAuthentication):\n    \"\"\"OAuth 2.0 token authentication\"\"\"\n    \n    def authenticate(self, request):\n        auth_header = request.META.get('HTTP_AUTHORIZATION')\n        if not auth_header or not auth_header.startswith('Bearer '):\n            return None\n        \n        token = auth_header.split(' ')[1]\n        \n        # Validate token with OAuth provider\n        user_info = self.validate_token(token)\n        if not user_info:\n            raise AuthenticationFailed('Invalid OAuth token')\n        \n        # Get or create user\n        user = self.get_or_create_user(user_info)\n        \n        return (user, token)\n    \n    def validate_token(self, token):\n        \"\"\"Validate token with OAuth provider\"\"\"\n        try:\n            response = requests.get(\n                settings.OAUTH_USERINFO_URL,\n                headers={'Authorization': f'Bearer {token}'},\n                timeout=10\n            )\n            \n            if response.status_code == 200:\n                return response.json()\n            \n            return None\n            \n        except requests.RequestException:\n            return None\n    \n    def get_or_create_user(self, user_info):\n        \"\"\"Get or create user from OAuth info\"\"\"\n        email = user_info.get('email')\n        if not email:\n            raise AuthenticationFailed('Email not provided by OAuth provider')\n        \n        user, created = User.objects.get_or_create(\n            email=email,\n            defaults={\n                'username': user_info.get('preferred_username', email),\n                'first_name': user_info.get('given_name', ''),\n                'last_name': user_info.get('family_name', ''),\n                'is_active': True\n            }\n        )\n        \n        return user\n",[1095,3490,3491,3496,3503,3517,3531,3545,3549,3562,3571,3575,3591,3617,3645,3651,3655,3679,3683,3688,3710,3721,3738,3742,3747,3767,3771,3785,3789,3806,3815,3821,3837,3848,3885,3895,3899,3903,3923,3937,3941,3947,3951,3964,3970,3974,3991,4000,4023,4034,4051,4055,4080,4091,4099,4131,4164,4196,4209,4214,4218,4222],{"__ignoreMap":1093},[1098,3492,3493],{"class":1100,"line":1101},[1098,3494,3495],{"class":1104},"# oauth.py\n",[1098,3497,3498,3500],{"class":1100,"line":1108},[1098,3499,1112],{"class":1111},[1098,3501,3502],{"class":1115}," requests\n",[1098,3504,3505,3507,3509,3511,3513,3515],{"class":1100,"line":1119},[1098,3506,1122],{"class":1111},[1098,3508,1145],{"class":1115},[1098,3510,1148],{"class":1133},[1098,3512,1151],{"class":1115},[1098,3514,1112],{"class":1111},[1098,3516,1156],{"class":1115},[1098,3518,3519,3521,3523,3525,3527,3529],{"class":1100,"line":1140},[1098,3520,1122],{"class":1111},[1098,3522,1186],{"class":1115},[1098,3524,1148],{"class":1133},[1098,3526,1191],{"class":1115},[1098,3528,1112],{"class":1111},[1098,3530,1196],{"class":1115},[1098,3532,3533,3535,3537,3539,3541,3543],{"class":1100,"line":1159},[1098,3534,1122],{"class":1111},[1098,3536,1186],{"class":1115},[1098,3538,1148],{"class":1133},[1098,3540,1208],{"class":1115},[1098,3542,1112],{"class":1111},[1098,3544,1213],{"class":1115},[1098,3546,3547],{"class":1100,"line":1181},[1098,3548,1220],{"emptyLinePlaceholder":1219},[1098,3550,3551,3553,3556,3558,3560],{"class":1100,"line":1199},[1098,3552,1248],{"class":1247},[1098,3554,3555],{"class":1251}," OAuth2Authentication",[1098,3557,1255],{"class":1133},[1098,3559,1259],{"class":1258},[1098,3561,1262],{"class":1133},[1098,3563,3564,3566,3569],{"class":1100,"line":1216},[1098,3565,1269],{"class":1268},[1098,3567,3568],{"class":1272},"OAuth 2.0 token authentication",[1098,3570,1276],{"class":1268},[1098,3572,3573],{"class":1100,"line":1223},[1098,3574,1282],{"class":1115},[1098,3576,3577,3579,3581,3583,3585,3587,3589],{"class":1100,"line":1239},[1098,3578,1288],{"class":1247},[1098,3580,1292],{"class":1291},[1098,3582,1255],{"class":1133},[1098,3584,1298],{"class":1297},[1098,3586,1134],{"class":1133},[1098,3588,1304],{"class":1303},[1098,3590,1262],{"class":1133},[1098,3592,3593,3595,3597,3599,3601,3603,3605,3607,3609,3611,3613,3615],{"class":1100,"line":1244},[1098,3594,1312],{"class":1115},[1098,3596,1229],{"class":1133},[1098,3598,1304],{"class":1115},[1098,3600,1148],{"class":1133},[1098,3602,1322],{"class":1321},[1098,3604,1148],{"class":1133},[1098,3606,1327],{"class":1232},[1098,3608,1255],{"class":1133},[1098,3610,1333],{"class":1332},[1098,3612,1337],{"class":1336},[1098,3614,1333],{"class":1332},[1098,3616,1342],{"class":1133},[1098,3618,3619,3621,3623,3625,3627,3629,3631,3633,3635,3637,3639,3641,3643],{"class":1100,"line":1265},[1098,3620,1348],{"class":1111},[1098,3622,1352],{"class":1351},[1098,3624,1355],{"class":1115},[1098,3626,1358],{"class":1351},[1098,3628,1352],{"class":1351},[1098,3630,1363],{"class":1115},[1098,3632,1148],{"class":1133},[1098,3634,1368],{"class":1232},[1098,3636,1255],{"class":1133},[1098,3638,1333],{"class":1332},[1098,3640,1375],{"class":1336},[1098,3642,1333],{"class":1332},[1098,3644,1262],{"class":1133},[1098,3646,3647,3649],{"class":1100,"line":1279},[1098,3648,1385],{"class":1111},[1098,3650,1389],{"class":1388},[1098,3652,3653],{"class":1100,"line":1285},[1098,3654,1395],{"class":1115},[1098,3656,3657,3659,3661,3663,3665,3667,3669,3671,3673,3675,3677],{"class":1100,"line":1309},[1098,3658,1401],{"class":1115},[1098,3660,1229],{"class":1133},[1098,3662,1363],{"class":1115},[1098,3664,1148],{"class":1133},[1098,3666,1410],{"class":1232},[1098,3668,1255],{"class":1133},[1098,3670,1333],{"class":1332},[1098,3672,1417],{"class":1332},[1098,3674,1420],{"class":1133},[1098,3676,1424],{"class":1423},[1098,3678,1427],{"class":1133},[1098,3680,3681],{"class":1100,"line":1345},[1098,3682,1395],{"class":1115},[1098,3684,3685],{"class":1100,"line":1382},[1098,3686,3687],{"class":1104},"        # Validate token with OAuth provider\n",[1098,3689,3690,3693,3695,3699,3701,3704,3706,3708],{"class":1100,"line":1392},[1098,3691,3692],{"class":1115},"        user_info ",[1098,3694,1229],{"class":1133},[1098,3696,3698],{"class":3697},"se3Ec"," self",[1098,3700,1148],{"class":1133},[1098,3702,3703],{"class":1232},"validate_token",[1098,3705,1255],{"class":1133},[1098,3707,2298],{"class":1232},[1098,3709,1342],{"class":1133},[1098,3711,3712,3714,3716,3719],{"class":1100,"line":1398},[1098,3713,1348],{"class":1111},[1098,3715,1352],{"class":1351},[1098,3717,3718],{"class":1115}," user_info",[1098,3720,1441],{"class":1133},[1098,3722,3723,3725,3727,3729,3731,3734,3736],{"class":1100,"line":1430},[1098,3724,1698],{"class":1111},[1098,3726,1566],{"class":1232},[1098,3728,1255],{"class":1133},[1098,3730,1333],{"class":1332},[1098,3732,3733],{"class":1336},"Invalid OAuth token",[1098,3735,1333],{"class":1332},[1098,3737,1342],{"class":1133},[1098,3739,3740],{"class":1100,"line":1435},[1098,3741,1395],{"class":1115},[1098,3743,3744],{"class":1100,"line":1444},[1098,3745,3746],{"class":1104},"        # Get or create user\n",[1098,3748,3749,3751,3753,3755,3757,3760,3762,3765],{"class":1100,"line":1463},[1098,3750,3303],{"class":1115},[1098,3752,1229],{"class":1133},[1098,3754,3698],{"class":3697},[1098,3756,1148],{"class":1133},[1098,3758,3759],{"class":1232},"get_or_create_user",[1098,3761,1255],{"class":1133},[1098,3763,3764],{"class":1232},"user_info",[1098,3766,1342],{"class":1133},[1098,3768,3769],{"class":1100,"line":1474},[1098,3770,1395],{"class":1115},[1098,3772,3773,3775,3777,3779,3781,3783],{"class":1100,"line":1489},[1098,3774,2016],{"class":1111},[1098,3776,1662],{"class":1133},[1098,3778,1665],{"class":1115},[1098,3780,1134],{"class":1133},[1098,3782,1670],{"class":1115},[1098,3784,1342],{"class":1133},[1098,3786,3787],{"class":1100,"line":1509},[1098,3788,1282],{"class":1115},[1098,3790,3791,3793,3796,3798,3800,3802,3804],{"class":1100,"line":1515},[1098,3792,1288],{"class":1247},[1098,3794,3795],{"class":1291}," validate_token",[1098,3797,1255],{"class":1133},[1098,3799,1298],{"class":1297},[1098,3801,1134],{"class":1133},[1098,3803,1670],{"class":1303},[1098,3805,1262],{"class":1133},[1098,3807,3808,3810,3813],{"class":1100,"line":1521},[1098,3809,1835],{"class":1268},[1098,3811,3812],{"class":1272},"Validate token with OAuth provider",[1098,3814,1276],{"class":1268},[1098,3816,3817,3819],{"class":1100,"line":1547},[1098,3818,1438],{"class":1111},[1098,3820,1441],{"class":1133},[1098,3822,3823,3826,3828,3831,3833,3835],{"class":1100,"line":1560},[1098,3824,3825],{"class":1115},"            response ",[1098,3827,1229],{"class":1133},[1098,3829,3830],{"class":1115}," requests",[1098,3832,1148],{"class":1133},[1098,3834,1327],{"class":1232},[1098,3836,1460],{"class":1133},[1098,3838,3839,3841,3843,3846],{"class":1100,"line":1580},[1098,3840,1477],{"class":1232},[1098,3842,1148],{"class":1133},[1098,3844,3845],{"class":1321},"OAUTH_USERINFO_URL",[1098,3847,1873],{"class":1133},[1098,3849,3850,3853,3856,3858,3861,3863,3865,3868,3871,3875,3877,3880,3882],{"class":1100,"line":1585},[1098,3851,3852],{"class":1492},"                headers",[1098,3854,3855],{"class":1133},"={",[1098,3857,1333],{"class":1332},[1098,3859,3860],{"class":1336},"Authorization",[1098,3862,1333],{"class":1332},[1098,3864,1864],{"class":1133},[1098,3866,3867],{"class":1247}," f",[1098,3869,3870],{"class":1336},"'Bearer ",[1098,3872,3874],{"class":3873},"s3h35","{",[1098,3876,2298],{"class":1232},[1098,3878,3879],{"class":3873},"}",[1098,3881,1333],{"class":1336},[1098,3883,3884],{"class":1133},"},\n",[1098,3886,3887,3890,3892],{"class":1100,"line":1617},[1098,3888,3889],{"class":1492},"                timeout",[1098,3891,1229],{"class":1133},[1098,3893,3894],{"class":1423},"10\n",[1098,3896,3897],{"class":1100,"line":1634},[1098,3898,1512],{"class":1133},[1098,3900,3901],{"class":1100,"line":1652},[1098,3902,1518],{"class":1115},[1098,3904,3905,3907,3910,3912,3915,3918,3921],{"class":1100,"line":1657},[1098,3906,1550],{"class":1111},[1098,3908,3909],{"class":1115}," response",[1098,3911,1148],{"class":1133},[1098,3913,3914],{"class":1598},"status_code",[1098,3916,3917],{"class":1351}," ==",[1098,3919,3920],{"class":1423}," 200",[1098,3922,1441],{"class":1133},[1098,3924,3925,3928,3930,3932,3935],{"class":1100,"line":1675},[1098,3926,3927],{"class":1111},"                return",[1098,3929,3909],{"class":1115},[1098,3931,1148],{"class":1133},[1098,3933,3934],{"class":1232},"json",[1098,3936,1236],{"class":1133},[1098,3938,3939],{"class":1100,"line":1680},[1098,3940,1518],{"class":1115},[1098,3942,3943,3945],{"class":1100,"line":1695},[1098,3944,1385],{"class":1111},[1098,3946,1389],{"class":1388},[1098,3948,3949],{"class":1100,"line":1714},[1098,3950,1518],{"class":1115},[1098,3952,3953,3955,3957,3959,3962],{"class":1100,"line":1728},[1098,3954,1683],{"class":1111},[1098,3956,3830],{"class":1115},[1098,3958,1148],{"class":1133},[1098,3960,3961],{"class":1598},"RequestException",[1098,3963,1441],{"class":1133},[1098,3965,3966,3968],{"class":1100,"line":1746},[1098,3967,1385],{"class":1111},[1098,3969,1389],{"class":1388},[1098,3971,3972],{"class":1100,"line":1760},[1098,3973,1282],{"class":1115},[1098,3975,3976,3978,3981,3983,3985,3987,3989],{"class":1100,"line":1778},[1098,3977,1288],{"class":1247},[1098,3979,3980],{"class":1291}," get_or_create_user",[1098,3982,1255],{"class":1133},[1098,3984,1298],{"class":1297},[1098,3986,1134],{"class":1133},[1098,3988,3718],{"class":1303},[1098,3990,1262],{"class":1133},[1098,3992,3993,3995,3998],{"class":1100,"line":1783},[1098,3994,1835],{"class":1268},[1098,3996,3997],{"class":1272},"Get or create user from OAuth info",[1098,3999,1276],{"class":1268},[1098,4001,4002,4005,4007,4009,4011,4013,4015,4017,4019,4021],{"class":1100,"line":1793},[1098,4003,4004],{"class":1115},"        email ",[1098,4006,1229],{"class":1133},[1098,4008,3718],{"class":1115},[1098,4010,1148],{"class":1133},[1098,4012,1327],{"class":1232},[1098,4014,1255],{"class":1133},[1098,4016,1333],{"class":1332},[1098,4018,1901],{"class":1336},[1098,4020,1333],{"class":1332},[1098,4022,1342],{"class":1133},[1098,4024,4025,4027,4029,4032],{"class":1100,"line":1803},[1098,4026,1348],{"class":1111},[1098,4028,1352],{"class":1351},[1098,4030,4031],{"class":1115}," email",[1098,4033,1441],{"class":1133},[1098,4035,4036,4038,4040,4042,4044,4047,4049],{"class":1100,"line":1808},[1098,4037,1698],{"class":1111},[1098,4039,1566],{"class":1232},[1098,4041,1255],{"class":1133},[1098,4043,1333],{"class":1332},[1098,4045,4046],{"class":1336},"Email not provided by OAuth provider",[1098,4048,1333],{"class":1332},[1098,4050,1342],{"class":1133},[1098,4052,4053],{"class":1100,"line":1818},[1098,4054,1395],{"class":1115},[1098,4056,4057,4060,4062,4065,4067,4069,4071,4073,4075,4078],{"class":1100,"line":1832},[1098,4058,4059],{"class":1115},"        user",[1098,4061,1134],{"class":1133},[1098,4063,4064],{"class":1115}," created ",[1098,4066,1229],{"class":1133},[1098,4068,1593],{"class":1115},[1098,4070,1148],{"class":1133},[1098,4072,1599],{"class":1598},[1098,4074,1148],{"class":1133},[1098,4076,4077],{"class":1232},"get_or_create",[1098,4079,1460],{"class":1133},[1098,4081,4082,4085,4087,4089],{"class":1100,"line":1843},[1098,4083,4084],{"class":1492},"            email",[1098,4086,1229],{"class":1133},[1098,4088,1901],{"class":1232},[1098,4090,1873],{"class":1133},[1098,4092,4093,4096],{"class":1100,"line":1854},[1098,4094,4095],{"class":1492},"            defaults",[1098,4097,4098],{"class":1133},"={\n",[1098,4100,4101,4104,4106,4108,4110,4112,4114,4116,4118,4120,4123,4125,4127,4129],{"class":1100,"line":1876},[1098,4102,4103],{"class":1332},"                '",[1098,4105,1881],{"class":1336},[1098,4107,1333],{"class":1332},[1098,4109,1864],{"class":1133},[1098,4111,3718],{"class":1232},[1098,4113,1148],{"class":1133},[1098,4115,1327],{"class":1232},[1098,4117,1255],{"class":1133},[1098,4119,1333],{"class":1332},[1098,4121,4122],{"class":1336},"preferred_username",[1098,4124,1333],{"class":1332},[1098,4126,1134],{"class":1133},[1098,4128,4031],{"class":1232},[1098,4130,1958],{"class":1133},[1098,4132,4133,4135,4138,4140,4142,4144,4146,4148,4150,4152,4155,4157,4159,4162],{"class":1100,"line":1896},[1098,4134,4103],{"class":1332},[1098,4136,4137],{"class":1336},"first_name",[1098,4139,1333],{"class":1332},[1098,4141,1864],{"class":1133},[1098,4143,3718],{"class":1232},[1098,4145,1148],{"class":1133},[1098,4147,1327],{"class":1232},[1098,4149,1255],{"class":1133},[1098,4151,1333],{"class":1332},[1098,4153,4154],{"class":1336},"given_name",[1098,4156,1333],{"class":1332},[1098,4158,1134],{"class":1133},[1098,4160,4161],{"class":1332}," ''",[1098,4163,1958],{"class":1133},[1098,4165,4166,4168,4171,4173,4175,4177,4179,4181,4183,4185,4188,4190,4192,4194],{"class":1100,"line":1916},[1098,4167,4103],{"class":1332},[1098,4169,4170],{"class":1336},"last_name",[1098,4172,1333],{"class":1332},[1098,4174,1864],{"class":1133},[1098,4176,3718],{"class":1232},[1098,4178,1148],{"class":1133},[1098,4180,1327],{"class":1232},[1098,4182,1255],{"class":1133},[1098,4184,1333],{"class":1332},[1098,4186,4187],{"class":1336},"family_name",[1098,4189,1333],{"class":1332},[1098,4191,1134],{"class":1133},[1098,4193,4161],{"class":1332},[1098,4195,1958],{"class":1133},[1098,4197,4198,4200,4202,4204,4206],{"class":1100,"line":1961},[1098,4199,4103],{"class":1332},[1098,4201,1629],{"class":1336},[1098,4203,1333],{"class":1332},[1098,4205,1864],{"class":1133},[1098,4207,4208],{"class":1388}," True\n",[1098,4210,4211],{"class":1100,"line":1982},[1098,4212,4213],{"class":1133},"            }\n",[1098,4215,4216],{"class":1100,"line":2002},[1098,4217,2070],{"class":1133},[1098,4219,4220],{"class":1100,"line":2008},[1098,4221,1395],{"class":1115},[1098,4223,4224,4226],{"class":1100,"line":2013},[1098,4225,2016],{"class":1111},[1098,4227,4228],{"class":1115}," user\n",[1035,4230,4232],{"id":4231},"_3-role-based-access-control-rbac","3. Role-Based Access Control (RBAC)",[1088,4234,4236],{"className":1090,"code":4235,"language":1092,"meta":1093,"style":1093},"# permissions.py\nfrom rest_framework.permissions import BasePermission\nfrom django.contrib.auth.models import Group\n\nclass RoleBasedPermission(BasePermission):\n    \"\"\"Role-based permission system\"\"\"\n    \n    required_roles = []\n    \n    def has_permission(self, request, view):\n        if not request.user or not request.user.is_authenticated:\n            return False\n        \n        if not self.required_roles:\n            return True\n        \n        user_roles = set(request.user.groups.values_list('name', flat=True))\n        required_roles = set(self.required_roles)\n        \n        return bool(user_roles.intersection(required_roles))\n\nclass AdminPermission(RoleBasedPermission):\n    required_roles = ['admin']\n\nclass ManagerPermission(RoleBasedPermission):\n    required_roles = ['admin', 'manager']\n\nclass UserPermission(RoleBasedPermission):\n    required_roles = ['admin', 'manager', 'user']\n\n# Custom permissions for specific actions\nclass IsOwnerOrAdmin(BasePermission):\n    \"\"\"Allow access to owners or admins\"\"\"\n    \n    def has_object_permission(self, request, view, obj):\n        # Admin can access everything\n        if request.user.groups.filter(name='admin').exists():\n            return True\n        \n        # Owner can access their own objects\n        if hasattr(obj, 'user'):\n            return obj.user == request.user\n        \n        return False\n\n# Usage in views\nfrom rest_framework.decorators import permission_classes\n\nclass UserViewSet(ModelViewSet):\n    permission_classes = [UserPermission]\n    \n    def get_permissions(self):\n        \"\"\"Apply different permissions based on action\"\"\"\n        if self.action == 'create':\n            permission_classes = [AllowAny]\n        elif self.action in ['update', 'partial_update', 'destroy']:\n            permission_classes = [IsOwnerOrAdmin]\n        else:\n            permission_classes = [UserPermission]\n        \n        return [permission() for permission in permission_classes]\n",[1095,4237,4238,4243,4258,4283,4287,4301,4310,4314,4324,4328,4350,4380,4387,4391,4406,4412,4416,4466,4485,4489,4512,4516,4530,4548,4552,4565,4590,4594,4607,4639,4643,4648,4661,4670,4674,4700,4705,4745,4751,4755,4760,4783,4802,4806,4812,4816,4821,4835,4839,4853,4867,4871,4884,4893,4915,4928,4972,4985,4992,5004,5008],{"__ignoreMap":1093},[1098,4239,4240],{"class":1100,"line":1101},[1098,4241,4242],{"class":1104},"# permissions.py\n",[1098,4244,4245,4247,4249,4251,4253,4255],{"class":1100,"line":1108},[1098,4246,1122],{"class":1111},[1098,4248,1186],{"class":1115},[1098,4250,1148],{"class":1133},[1098,4252,2566],{"class":1115},[1098,4254,1112],{"class":1111},[1098,4256,4257],{"class":1115}," BasePermission\n",[1098,4259,4260,4262,4264,4266,4268,4270,4273,4275,4278,4280],{"class":1100,"line":1119},[1098,4261,1122],{"class":1111},[1098,4263,1145],{"class":1115},[1098,4265,1148],{"class":1133},[1098,4267,1168],{"class":1115},[1098,4269,1148],{"class":1133},[1098,4271,4272],{"class":1115},"auth",[1098,4274,1148],{"class":1133},[1098,4276,4277],{"class":1115},"models ",[1098,4279,1112],{"class":1111},[1098,4281,4282],{"class":1115}," Group\n",[1098,4284,4285],{"class":1100,"line":1140},[1098,4286,1220],{"emptyLinePlaceholder":1219},[1098,4288,4289,4291,4294,4296,4299],{"class":1100,"line":1159},[1098,4290,1248],{"class":1247},[1098,4292,4293],{"class":1251}," RoleBasedPermission",[1098,4295,1255],{"class":1133},[1098,4297,4298],{"class":1258},"BasePermission",[1098,4300,1262],{"class":1133},[1098,4302,4303,4305,4308],{"class":1100,"line":1181},[1098,4304,1269],{"class":1268},[1098,4306,4307],{"class":1272},"Role-based permission system",[1098,4309,1276],{"class":1268},[1098,4311,4312],{"class":1100,"line":1199},[1098,4313,1282],{"class":1115},[1098,4315,4316,4319,4321],{"class":1100,"line":1216},[1098,4317,4318],{"class":1115},"    required_roles ",[1098,4320,1229],{"class":1133},[1098,4322,4323],{"class":1133}," []\n",[1098,4325,4326],{"class":1100,"line":1223},[1098,4327,1282],{"class":1115},[1098,4329,4330,4332,4335,4337,4339,4341,4343,4345,4348],{"class":1100,"line":1239},[1098,4331,1288],{"class":1247},[1098,4333,4334],{"class":1291}," has_permission",[1098,4336,1255],{"class":1133},[1098,4338,1298],{"class":1297},[1098,4340,1134],{"class":1133},[1098,4342,1304],{"class":1303},[1098,4344,1134],{"class":1133},[1098,4346,4347],{"class":1303}," view",[1098,4349,1262],{"class":1133},[1098,4351,4352,4354,4356,4358,4360,4362,4365,4367,4369,4371,4373,4375,4378],{"class":1100,"line":1244},[1098,4353,1348],{"class":1111},[1098,4355,1352],{"class":1351},[1098,4357,1304],{"class":1115},[1098,4359,1148],{"class":1133},[1098,4361,1665],{"class":1598},[1098,4363,4364],{"class":1351}," or",[1098,4366,1352],{"class":1351},[1098,4368,1304],{"class":1115},[1098,4370,1148],{"class":1133},[1098,4372,1665],{"class":1598},[1098,4374,1148],{"class":1133},[1098,4376,4377],{"class":1598},"is_authenticated",[1098,4379,1441],{"class":1133},[1098,4381,4382,4384],{"class":1100,"line":1265},[1098,4383,1385],{"class":1111},[1098,4385,4386],{"class":1388}," False\n",[1098,4388,4389],{"class":1100,"line":1279},[1098,4390,1395],{"class":1115},[1098,4392,4393,4395,4397,4399,4401,4404],{"class":1100,"line":1285},[1098,4394,1348],{"class":1111},[1098,4396,1352],{"class":1351},[1098,4398,3698],{"class":3697},[1098,4400,1148],{"class":1133},[1098,4402,4403],{"class":1598},"required_roles",[1098,4405,1441],{"class":1133},[1098,4407,4408,4410],{"class":1100,"line":1309},[1098,4409,1385],{"class":1111},[1098,4411,4208],{"class":1388},[1098,4413,4414],{"class":1100,"line":1345},[1098,4415,1395],{"class":1115},[1098,4417,4418,4421,4423,4426,4428,4430,4432,4434,4436,4439,4441,4444,4446,4448,4451,4453,4455,4458,4460,4463],{"class":1100,"line":1382},[1098,4419,4420],{"class":1115},"        user_roles ",[1098,4422,1229],{"class":1133},[1098,4424,4425],{"class":1814}," set",[1098,4427,1255],{"class":1133},[1098,4429,2677],{"class":1232},[1098,4431,1148],{"class":1133},[1098,4433,1665],{"class":1598},[1098,4435,1148],{"class":1133},[1098,4437,4438],{"class":1598},"groups",[1098,4440,1148],{"class":1133},[1098,4442,4443],{"class":1232},"values_list",[1098,4445,1255],{"class":1133},[1098,4447,1333],{"class":1332},[1098,4449,4450],{"class":1336},"name",[1098,4452,1333],{"class":1332},[1098,4454,1134],{"class":1133},[1098,4456,4457],{"class":1492}," flat",[1098,4459,1229],{"class":1133},[1098,4461,4462],{"class":1388},"True",[1098,4464,4465],{"class":1133},"))\n",[1098,4467,4468,4471,4473,4475,4477,4479,4481,4483],{"class":1100,"line":1392},[1098,4469,4470],{"class":1115},"        required_roles ",[1098,4472,1229],{"class":1133},[1098,4474,4425],{"class":1814},[1098,4476,1255],{"class":1133},[1098,4478,1298],{"class":3697},[1098,4480,1148],{"class":1133},[1098,4482,4403],{"class":1598},[1098,4484,1342],{"class":1133},[1098,4486,4487],{"class":1100,"line":1398},[1098,4488,1395],{"class":1115},[1098,4490,4491,4493,4496,4498,4501,4503,4506,4508,4510],{"class":1100,"line":1430},[1098,4492,2016],{"class":1111},[1098,4494,4495],{"class":1814}," bool",[1098,4497,1255],{"class":1133},[1098,4499,4500],{"class":1232},"user_roles",[1098,4502,1148],{"class":1133},[1098,4504,4505],{"class":1232},"intersection",[1098,4507,1255],{"class":1133},[1098,4509,4403],{"class":1232},[1098,4511,4465],{"class":1133},[1098,4513,4514],{"class":1100,"line":1435},[1098,4515,1220],{"emptyLinePlaceholder":1219},[1098,4517,4518,4520,4523,4525,4528],{"class":1100,"line":1444},[1098,4519,1248],{"class":1247},[1098,4521,4522],{"class":1251}," AdminPermission",[1098,4524,1255],{"class":1133},[1098,4526,4527],{"class":1258},"RoleBasedPermission",[1098,4529,1262],{"class":1133},[1098,4531,4532,4534,4536,4539,4541,4544,4546],{"class":1100,"line":1463},[1098,4533,4318],{"class":1115},[1098,4535,1229],{"class":1133},[1098,4537,4538],{"class":1133}," [",[1098,4540,1333],{"class":1332},[1098,4542,4543],{"class":1336},"admin",[1098,4545,1333],{"class":1332},[1098,4547,1427],{"class":1133},[1098,4549,4550],{"class":1100,"line":1474},[1098,4551,1220],{"emptyLinePlaceholder":1219},[1098,4553,4554,4556,4559,4561,4563],{"class":1100,"line":1489},[1098,4555,1248],{"class":1247},[1098,4557,4558],{"class":1251}," ManagerPermission",[1098,4560,1255],{"class":1133},[1098,4562,4527],{"class":1258},[1098,4564,1262],{"class":1133},[1098,4566,4567,4569,4571,4573,4575,4577,4579,4581,4583,4586,4588],{"class":1100,"line":1509},[1098,4568,4318],{"class":1115},[1098,4570,1229],{"class":1133},[1098,4572,4538],{"class":1133},[1098,4574,1333],{"class":1332},[1098,4576,4543],{"class":1336},[1098,4578,1333],{"class":1332},[1098,4580,1134],{"class":1133},[1098,4582,1417],{"class":1332},[1098,4584,4585],{"class":1336},"manager",[1098,4587,1333],{"class":1332},[1098,4589,1427],{"class":1133},[1098,4591,4592],{"class":1100,"line":1515},[1098,4593,1220],{"emptyLinePlaceholder":1219},[1098,4595,4596,4598,4601,4603,4605],{"class":1100,"line":1521},[1098,4597,1248],{"class":1247},[1098,4599,4600],{"class":1251}," UserPermission",[1098,4602,1255],{"class":1133},[1098,4604,4527],{"class":1258},[1098,4606,1262],{"class":1133},[1098,4608,4609,4611,4613,4615,4617,4619,4621,4623,4625,4627,4629,4631,4633,4635,4637],{"class":1100,"line":1547},[1098,4610,4318],{"class":1115},[1098,4612,1229],{"class":1133},[1098,4614,4538],{"class":1133},[1098,4616,1333],{"class":1332},[1098,4618,4543],{"class":1336},[1098,4620,1333],{"class":1332},[1098,4622,1134],{"class":1133},[1098,4624,1417],{"class":1332},[1098,4626,4585],{"class":1336},[1098,4628,1333],{"class":1332},[1098,4630,1134],{"class":1133},[1098,4632,1417],{"class":1332},[1098,4634,1665],{"class":1336},[1098,4636,1333],{"class":1332},[1098,4638,1427],{"class":1133},[1098,4640,4641],{"class":1100,"line":1560},[1098,4642,1220],{"emptyLinePlaceholder":1219},[1098,4644,4645],{"class":1100,"line":1580},[1098,4646,4647],{"class":1104},"# Custom permissions for specific actions\n",[1098,4649,4650,4652,4655,4657,4659],{"class":1100,"line":1585},[1098,4651,1248],{"class":1247},[1098,4653,4654],{"class":1251}," IsOwnerOrAdmin",[1098,4656,1255],{"class":1133},[1098,4658,4298],{"class":1258},[1098,4660,1262],{"class":1133},[1098,4662,4663,4665,4668],{"class":1100,"line":1617},[1098,4664,1269],{"class":1268},[1098,4666,4667],{"class":1272},"Allow access to owners or admins",[1098,4669,1276],{"class":1268},[1098,4671,4672],{"class":1100,"line":1634},[1098,4673,1282],{"class":1115},[1098,4675,4676,4678,4681,4683,4685,4687,4689,4691,4693,4695,4698],{"class":1100,"line":1652},[1098,4677,1288],{"class":1247},[1098,4679,4680],{"class":1291}," has_object_permission",[1098,4682,1255],{"class":1133},[1098,4684,1298],{"class":1297},[1098,4686,1134],{"class":1133},[1098,4688,1304],{"class":1303},[1098,4690,1134],{"class":1133},[1098,4692,4347],{"class":1303},[1098,4694,1134],{"class":1133},[1098,4696,4697],{"class":1303}," obj",[1098,4699,1262],{"class":1133},[1098,4701,4702],{"class":1100,"line":1657},[1098,4703,4704],{"class":1104},"        # Admin can access everything\n",[1098,4706,4707,4709,4711,4713,4715,4717,4719,4721,4724,4726,4728,4730,4732,4734,4736,4739,4742],{"class":1100,"line":1675},[1098,4708,1348],{"class":1111},[1098,4710,1304],{"class":1115},[1098,4712,1148],{"class":1133},[1098,4714,1665],{"class":1598},[1098,4716,1148],{"class":1133},[1098,4718,4438],{"class":1598},[1098,4720,1148],{"class":1133},[1098,4722,4723],{"class":1232},"filter",[1098,4725,1255],{"class":1133},[1098,4727,4450],{"class":1492},[1098,4729,1229],{"class":1133},[1098,4731,1333],{"class":1332},[1098,4733,4543],{"class":1336},[1098,4735,1333],{"class":1332},[1098,4737,4738],{"class":1133},").",[1098,4740,4741],{"class":1232},"exists",[1098,4743,4744],{"class":1133},"():\n",[1098,4746,4747,4749],{"class":1100,"line":1680},[1098,4748,1385],{"class":1111},[1098,4750,4208],{"class":1388},[1098,4752,4753],{"class":1100,"line":1695},[1098,4754,1395],{"class":1115},[1098,4756,4757],{"class":1100,"line":1714},[1098,4758,4759],{"class":1104},"        # Owner can access their own objects\n",[1098,4761,4762,4764,4768,4770,4773,4775,4777,4779,4781],{"class":1100,"line":1728},[1098,4763,1348],{"class":1111},[1098,4765,4767],{"class":4766},"sJdAF"," hasattr",[1098,4769,1255],{"class":1133},[1098,4771,4772],{"class":1232},"obj",[1098,4774,1134],{"class":1133},[1098,4776,1417],{"class":1332},[1098,4778,1665],{"class":1336},[1098,4780,1333],{"class":1332},[1098,4782,1262],{"class":1133},[1098,4784,4785,4787,4789,4791,4793,4795,4797,4799],{"class":1100,"line":1746},[1098,4786,1385],{"class":1111},[1098,4788,4697],{"class":1115},[1098,4790,1148],{"class":1133},[1098,4792,1665],{"class":1598},[1098,4794,3917],{"class":1351},[1098,4796,1304],{"class":1115},[1098,4798,1148],{"class":1133},[1098,4800,4801],{"class":1598},"user\n",[1098,4803,4804],{"class":1100,"line":1760},[1098,4805,1395],{"class":1115},[1098,4807,4808,4810],{"class":1100,"line":1778},[1098,4809,2016],{"class":1111},[1098,4811,4386],{"class":1388},[1098,4813,4814],{"class":1100,"line":1783},[1098,4815,1220],{"emptyLinePlaceholder":1219},[1098,4817,4818],{"class":1100,"line":1793},[1098,4819,4820],{"class":1104},"# Usage in views\n",[1098,4822,4823,4825,4827,4829,4831,4833],{"class":1100,"line":1803},[1098,4824,1122],{"class":1111},[1098,4826,1186],{"class":1115},[1098,4828,1148],{"class":1133},[1098,4830,2544],{"class":1115},[1098,4832,1112],{"class":1111},[1098,4834,2554],{"class":1115},[1098,4836,4837],{"class":1100,"line":1808},[1098,4838,1220],{"emptyLinePlaceholder":1219},[1098,4840,4841,4843,4846,4848,4851],{"class":1100,"line":1818},[1098,4842,1248],{"class":1247},[1098,4844,4845],{"class":1251}," UserViewSet",[1098,4847,1255],{"class":1133},[1098,4849,4850],{"class":1258},"ModelViewSet",[1098,4852,1262],{"class":1133},[1098,4854,4855,4858,4860,4862,4865],{"class":1100,"line":1832},[1098,4856,4857],{"class":1115},"    permission_classes ",[1098,4859,1229],{"class":1133},[1098,4861,4538],{"class":1133},[1098,4863,4864],{"class":1115},"UserPermission",[1098,4866,1427],{"class":1133},[1098,4868,4869],{"class":1100,"line":1843},[1098,4870,1282],{"class":1115},[1098,4872,4873,4875,4878,4880,4882],{"class":1100,"line":1854},[1098,4874,1288],{"class":1247},[1098,4876,4877],{"class":1291}," get_permissions",[1098,4879,1255],{"class":1133},[1098,4881,1298],{"class":1297},[1098,4883,1262],{"class":1133},[1098,4885,4886,4888,4891],{"class":1100,"line":1876},[1098,4887,1835],{"class":1268},[1098,4889,4890],{"class":1272},"Apply different permissions based on action",[1098,4892,1276],{"class":1268},[1098,4894,4895,4897,4899,4901,4904,4906,4908,4911,4913],{"class":1100,"line":1896},[1098,4896,1348],{"class":1111},[1098,4898,3698],{"class":3697},[1098,4900,1148],{"class":1133},[1098,4902,4903],{"class":1598},"action",[1098,4905,3917],{"class":1351},[1098,4907,1417],{"class":1332},[1098,4909,4910],{"class":1336},"create",[1098,4912,1333],{"class":1332},[1098,4914,1441],{"class":1133},[1098,4916,4917,4920,4922,4924,4926],{"class":1100,"line":1916},[1098,4918,4919],{"class":1115},"            permission_classes ",[1098,4921,1229],{"class":1133},[1098,4923,4538],{"class":1133},[1098,4925,2661],{"class":1115},[1098,4927,1427],{"class":1133},[1098,4929,4930,4933,4935,4937,4939,4942,4944,4946,4949,4951,4953,4955,4958,4960,4962,4964,4967,4969],{"class":1100,"line":1961},[1098,4931,4932],{"class":1111},"        elif",[1098,4934,3698],{"class":3697},[1098,4936,1148],{"class":1133},[1098,4938,4903],{"class":1598},[1098,4940,4941],{"class":1351}," in",[1098,4943,4538],{"class":1133},[1098,4945,1333],{"class":1332},[1098,4947,4948],{"class":1336},"update",[1098,4950,1333],{"class":1332},[1098,4952,1134],{"class":1133},[1098,4954,1417],{"class":1332},[1098,4956,4957],{"class":1336},"partial_update",[1098,4959,1333],{"class":1332},[1098,4961,1134],{"class":1133},[1098,4963,1417],{"class":1332},[1098,4965,4966],{"class":1336},"destroy",[1098,4968,1333],{"class":1332},[1098,4970,4971],{"class":1133},"]:\n",[1098,4973,4974,4976,4978,4980,4983],{"class":1100,"line":1982},[1098,4975,4919],{"class":1115},[1098,4977,1229],{"class":1133},[1098,4979,4538],{"class":1133},[1098,4981,4982],{"class":1115},"IsOwnerOrAdmin",[1098,4984,1427],{"class":1133},[1098,4986,4987,4990],{"class":1100,"line":2002},[1098,4988,4989],{"class":1111},"        else",[1098,4991,1441],{"class":1133},[1098,4993,4994,4996,4998,5000,5002],{"class":1100,"line":2008},[1098,4995,4919],{"class":1115},[1098,4997,1229],{"class":1133},[1098,4999,4538],{"class":1133},[1098,5001,4864],{"class":1115},[1098,5003,1427],{"class":1133},[1098,5005,5006],{"class":1100,"line":2013},[1098,5007,1395],{"class":1115},[1098,5009,5010,5012,5014,5017,5019,5022,5025,5028,5031],{"class":1100,"line":2028},[1098,5011,2016],{"class":1111},[1098,5013,4538],{"class":1133},[1098,5015,5016],{"class":1232},"permission",[1098,5018,1935],{"class":1133},[1098,5020,5021],{"class":1111}," for",[1098,5023,5024],{"class":1115}," permission ",[1098,5026,5027],{"class":1111},"in",[1098,5029,5030],{"class":1115}," permission_classes",[1098,5032,1427],{"class":1133},[1030,5034,5036],{"id":5035},"service-to-service-security","Service-to-Service Security",[1035,5038,5040],{"id":5039},"_1-service-authentication","1. Service Authentication",[1088,5042,5044],{"className":1090,"code":5043,"language":1092,"meta":1093,"style":1093},"# service_auth.py\nimport hmac\nimport hashlib\nimport time\nfrom django.conf import settings\nfrom rest_framework.authentication import BaseAuthentication\nfrom rest_framework.exceptions import AuthenticationFailed\n\nclass ServiceTokenAuthentication(BaseAuthentication):\n    \"\"\"Service-to-service token authentication\"\"\"\n    \n    def authenticate(self, request):\n        service_token = request.META.get('HTTP_X_SERVICE_TOKEN')\n        service_name = request.META.get('HTTP_X_SERVICE_NAME')\n        timestamp = request.META.get('HTTP_X_TIMESTAMP')\n        signature = request.META.get('HTTP_X_SIGNATURE')\n        \n        if not all([service_token, service_name, timestamp, signature]):\n            return None\n        \n        # Verify timestamp (prevent replay attacks)\n        try:\n            request_time = float(timestamp)\n            current_time = time.time()\n            \n            if abs(current_time - request_time) > 300:  # 5 minutes\n                raise AuthenticationFailed('Request timestamp too old')\n        except ValueError:\n            raise AuthenticationFailed('Invalid timestamp')\n        \n        # Verify service token\n        if service_token != settings.SERVICE_TOKENS.get(service_name):\n            raise AuthenticationFailed('Invalid service token')\n        \n        # Verify signature\n        expected_signature = self.generate_signature(\n            service_name, timestamp, service_token\n        )\n        \n        if not hmac.compare_digest(signature, expected_signature):\n            raise AuthenticationFailed('Invalid signature')\n        \n        # Create service user object\n        service_user = ServiceUser(service_name)\n        \n        return (service_user, service_token)\n    \n    def generate_signature(self, service_name, timestamp, service_token):\n        \"\"\"Generate HMAC signature\"\"\"\n        message = f\"{service_name}:{timestamp}:{service_token}\"\n        \n        return hmac.new(\n            settings.SERVICE_SECRET_KEY.encode(),\n            message.encode(),\n            hashlib.sha256\n        ).hexdigest()\n\nclass ServiceUser:\n    \"\"\"Represents a service user for authentication\"\"\"\n    \n    def __init__(self, service_name):\n        self.service_name = service_name\n        self.is_authenticated = True\n        self.is_service = True\n    \n    @property\n    def is_anonymous(self):\n        return False\n\nclass ServiceClient:\n    \"\"\"Client for making authenticated service calls\"\"\"\n    \n    def __init__(self, service_name):\n        self.service_name = service_name\n        self.service_token = settings.SERVICE_TOKENS[service_name]\n    \n    def make_request(self, method, url, **kwargs):\n        \"\"\"Make authenticated request to another service\"\"\"\n        timestamp = str(time.time())\n        signature = self.generate_signature(timestamp)\n        \n        headers = kwargs.get('headers', {})\n        headers.update({\n            'X-Service-Token': self.service_token,\n            'X-Service-Name': settings.SERVICE_NAME,\n            'X-Timestamp': timestamp,\n            'X-Signature': signature\n        })\n        kwargs['headers'] = headers\n        \n        return requests.request(method, url, **kwargs)\n    \n    def generate_signature(self, timestamp):\n        \"\"\"Generate request signature\"\"\"\n        message = f\"{settings.SERVICE_NAME}:{timestamp}:{self.service_token}\"\n        \n        return hmac.new(\n            settings.SERVICE_SECRET_KEY.encode(),\n            message.encode(),\n            hashlib.sha256\n        ).hexdigest()\n",[1095,5045,5046,5051,5058,5065,5072,5086,5100,5114,5118,5131,5140,5144,5160,5188,5216,5244,5272,5276,5308,5314,5318,5323,5329,5346,5363,5367,5398,5415,5424,5441,5445,5450,5479,5496,5500,5505,5521,5535,5539,5543,5569,5586,5590,5595,5611,5615,5631,5635,5660,5669,5706,5710,5723,5738,5749,5759,5769,5773,5781,5790,5794,5811,5826,5838,5851,5855,5862,5875,5881,5885,5894,5903,5907,5923,5935,5957,5961,5992,6001,6020,6038,6042,6070,6081,6100,6120,6135,6149,6153,6174,6178,6205,6209,6225,6234,6276,6280,6292,6306,6316,6324],{"__ignoreMap":1093},[1098,5047,5048],{"class":1100,"line":1101},[1098,5049,5050],{"class":1104},"# service_auth.py\n",[1098,5052,5053,5055],{"class":1100,"line":1108},[1098,5054,1112],{"class":1111},[1098,5056,5057],{"class":1115}," hmac\n",[1098,5059,5060,5062],{"class":1100,"line":1119},[1098,5061,1112],{"class":1111},[1098,5063,5064],{"class":1115}," hashlib\n",[1098,5066,5067,5069],{"class":1100,"line":1140},[1098,5068,1112],{"class":1111},[1098,5070,5071],{"class":1115}," time\n",[1098,5073,5074,5076,5078,5080,5082,5084],{"class":1100,"line":1159},[1098,5075,1122],{"class":1111},[1098,5077,1145],{"class":1115},[1098,5079,1148],{"class":1133},[1098,5081,1151],{"class":1115},[1098,5083,1112],{"class":1111},[1098,5085,1156],{"class":1115},[1098,5087,5088,5090,5092,5094,5096,5098],{"class":1100,"line":1181},[1098,5089,1122],{"class":1111},[1098,5091,1186],{"class":1115},[1098,5093,1148],{"class":1133},[1098,5095,1191],{"class":1115},[1098,5097,1112],{"class":1111},[1098,5099,1196],{"class":1115},[1098,5101,5102,5104,5106,5108,5110,5112],{"class":1100,"line":1199},[1098,5103,1122],{"class":1111},[1098,5105,1186],{"class":1115},[1098,5107,1148],{"class":1133},[1098,5109,1208],{"class":1115},[1098,5111,1112],{"class":1111},[1098,5113,1213],{"class":1115},[1098,5115,5116],{"class":1100,"line":1216},[1098,5117,1220],{"emptyLinePlaceholder":1219},[1098,5119,5120,5122,5125,5127,5129],{"class":1100,"line":1223},[1098,5121,1248],{"class":1247},[1098,5123,5124],{"class":1251}," ServiceTokenAuthentication",[1098,5126,1255],{"class":1133},[1098,5128,1259],{"class":1258},[1098,5130,1262],{"class":1133},[1098,5132,5133,5135,5138],{"class":1100,"line":1239},[1098,5134,1269],{"class":1268},[1098,5136,5137],{"class":1272},"Service-to-service token authentication",[1098,5139,1276],{"class":1268},[1098,5141,5142],{"class":1100,"line":1244},[1098,5143,1282],{"class":1115},[1098,5145,5146,5148,5150,5152,5154,5156,5158],{"class":1100,"line":1265},[1098,5147,1288],{"class":1247},[1098,5149,1292],{"class":1291},[1098,5151,1255],{"class":1133},[1098,5153,1298],{"class":1297},[1098,5155,1134],{"class":1133},[1098,5157,1304],{"class":1303},[1098,5159,1262],{"class":1133},[1098,5161,5162,5165,5167,5169,5171,5173,5175,5177,5179,5181,5184,5186],{"class":1100,"line":1279},[1098,5163,5164],{"class":1115},"        service_token ",[1098,5166,1229],{"class":1133},[1098,5168,1304],{"class":1115},[1098,5170,1148],{"class":1133},[1098,5172,1322],{"class":1321},[1098,5174,1148],{"class":1133},[1098,5176,1327],{"class":1232},[1098,5178,1255],{"class":1133},[1098,5180,1333],{"class":1332},[1098,5182,5183],{"class":1336},"HTTP_X_SERVICE_TOKEN",[1098,5185,1333],{"class":1332},[1098,5187,1342],{"class":1133},[1098,5189,5190,5193,5195,5197,5199,5201,5203,5205,5207,5209,5212,5214],{"class":1100,"line":1285},[1098,5191,5192],{"class":1115},"        service_name ",[1098,5194,1229],{"class":1133},[1098,5196,1304],{"class":1115},[1098,5198,1148],{"class":1133},[1098,5200,1322],{"class":1321},[1098,5202,1148],{"class":1133},[1098,5204,1327],{"class":1232},[1098,5206,1255],{"class":1133},[1098,5208,1333],{"class":1332},[1098,5210,5211],{"class":1336},"HTTP_X_SERVICE_NAME",[1098,5213,1333],{"class":1332},[1098,5215,1342],{"class":1133},[1098,5217,5218,5221,5223,5225,5227,5229,5231,5233,5235,5237,5240,5242],{"class":1100,"line":1309},[1098,5219,5220],{"class":1115},"        timestamp ",[1098,5222,1229],{"class":1133},[1098,5224,1304],{"class":1115},[1098,5226,1148],{"class":1133},[1098,5228,1322],{"class":1321},[1098,5230,1148],{"class":1133},[1098,5232,1327],{"class":1232},[1098,5234,1255],{"class":1133},[1098,5236,1333],{"class":1332},[1098,5238,5239],{"class":1336},"HTTP_X_TIMESTAMP",[1098,5241,1333],{"class":1332},[1098,5243,1342],{"class":1133},[1098,5245,5246,5249,5251,5253,5255,5257,5259,5261,5263,5265,5268,5270],{"class":1100,"line":1345},[1098,5247,5248],{"class":1115},"        signature ",[1098,5250,1229],{"class":1133},[1098,5252,1304],{"class":1115},[1098,5254,1148],{"class":1133},[1098,5256,1322],{"class":1321},[1098,5258,1148],{"class":1133},[1098,5260,1327],{"class":1232},[1098,5262,1255],{"class":1133},[1098,5264,1333],{"class":1332},[1098,5266,5267],{"class":1336},"HTTP_X_SIGNATURE",[1098,5269,1333],{"class":1332},[1098,5271,1342],{"class":1133},[1098,5273,5274],{"class":1100,"line":1382},[1098,5275,1395],{"class":1115},[1098,5277,5278,5280,5282,5285,5287,5290,5292,5295,5297,5300,5302,5305],{"class":1100,"line":1392},[1098,5279,1348],{"class":1111},[1098,5281,1352],{"class":1351},[1098,5283,5284],{"class":4766}," all",[1098,5286,2638],{"class":1133},[1098,5288,5289],{"class":1232},"service_token",[1098,5291,1134],{"class":1133},[1098,5293,5294],{"class":1232}," service_name",[1098,5296,1134],{"class":1133},[1098,5298,5299],{"class":1232}," timestamp",[1098,5301,1134],{"class":1133},[1098,5303,5304],{"class":1232}," signature",[1098,5306,5307],{"class":1133},"]):\n",[1098,5309,5310,5312],{"class":1100,"line":1398},[1098,5311,1385],{"class":1111},[1098,5313,1389],{"class":1388},[1098,5315,5316],{"class":1100,"line":1430},[1098,5317,1395],{"class":1115},[1098,5319,5320],{"class":1100,"line":1435},[1098,5321,5322],{"class":1104},"        # Verify timestamp (prevent replay attacks)\n",[1098,5324,5325,5327],{"class":1100,"line":1444},[1098,5326,1438],{"class":1111},[1098,5328,1441],{"class":1133},[1098,5330,5331,5334,5336,5339,5341,5344],{"class":1100,"line":1463},[1098,5332,5333],{"class":1115},"            request_time ",[1098,5335,1229],{"class":1133},[1098,5337,5338],{"class":1814}," float",[1098,5340,1255],{"class":1133},[1098,5342,5343],{"class":1232},"timestamp",[1098,5345,1342],{"class":1133},[1098,5347,5348,5351,5353,5356,5358,5361],{"class":1100,"line":1474},[1098,5349,5350],{"class":1115},"            current_time ",[1098,5352,1229],{"class":1133},[1098,5354,5355],{"class":1115}," time",[1098,5357,1148],{"class":1133},[1098,5359,5360],{"class":1232},"time",[1098,5362,1236],{"class":1133},[1098,5364,5365],{"class":1100,"line":1489},[1098,5366,1518],{"class":1115},[1098,5368,5369,5371,5374,5376,5379,5382,5385,5387,5390,5393,5395],{"class":1100,"line":1509},[1098,5370,1550],{"class":1111},[1098,5372,5373],{"class":4766}," abs",[1098,5375,1255],{"class":1133},[1098,5377,5378],{"class":1232},"current_time ",[1098,5380,5381],{"class":1351},"-",[1098,5383,5384],{"class":1232}," request_time",[1098,5386,2414],{"class":1133},[1098,5388,5389],{"class":1351}," >",[1098,5391,5392],{"class":1423}," 300",[1098,5394,1864],{"class":1133},[1098,5396,5397],{"class":1104},"  # 5 minutes\n",[1098,5399,5400,5402,5404,5406,5408,5411,5413],{"class":1100,"line":1515},[1098,5401,1563],{"class":1111},[1098,5403,1566],{"class":1232},[1098,5405,1255],{"class":1133},[1098,5407,1333],{"class":1332},[1098,5409,5410],{"class":1336},"Request timestamp too old",[1098,5412,1333],{"class":1332},[1098,5414,1342],{"class":1133},[1098,5416,5417,5419,5422],{"class":1100,"line":1521},[1098,5418,1683],{"class":1111},[1098,5420,5421],{"class":1814}," ValueError",[1098,5423,1441],{"class":1133},[1098,5425,5426,5428,5430,5432,5434,5437,5439],{"class":1100,"line":1547},[1098,5427,1698],{"class":1111},[1098,5429,1566],{"class":1232},[1098,5431,1255],{"class":1133},[1098,5433,1333],{"class":1332},[1098,5435,5436],{"class":1336},"Invalid timestamp",[1098,5438,1333],{"class":1332},[1098,5440,1342],{"class":1133},[1098,5442,5443],{"class":1100,"line":1560},[1098,5444,1395],{"class":1115},[1098,5446,5447],{"class":1100,"line":1580},[1098,5448,5449],{"class":1104},"        # Verify service token\n",[1098,5451,5452,5454,5457,5460,5463,5465,5468,5470,5472,5474,5477],{"class":1100,"line":1585},[1098,5453,1348],{"class":1111},[1098,5455,5456],{"class":1115}," service_token ",[1098,5458,5459],{"class":1351},"!=",[1098,5461,5462],{"class":1115}," settings",[1098,5464,1148],{"class":1133},[1098,5466,5467],{"class":1321},"SERVICE_TOKENS",[1098,5469,1148],{"class":1133},[1098,5471,1327],{"class":1232},[1098,5473,1255],{"class":1133},[1098,5475,5476],{"class":1232},"service_name",[1098,5478,1262],{"class":1133},[1098,5480,5481,5483,5485,5487,5489,5492,5494],{"class":1100,"line":1617},[1098,5482,1698],{"class":1111},[1098,5484,1566],{"class":1232},[1098,5486,1255],{"class":1133},[1098,5488,1333],{"class":1332},[1098,5490,5491],{"class":1336},"Invalid service token",[1098,5493,1333],{"class":1332},[1098,5495,1342],{"class":1133},[1098,5497,5498],{"class":1100,"line":1634},[1098,5499,1395],{"class":1115},[1098,5501,5502],{"class":1100,"line":1652},[1098,5503,5504],{"class":1104},"        # Verify signature\n",[1098,5506,5507,5510,5512,5514,5516,5519],{"class":1100,"line":1657},[1098,5508,5509],{"class":1115},"        expected_signature ",[1098,5511,1229],{"class":1133},[1098,5513,3698],{"class":3697},[1098,5515,1148],{"class":1133},[1098,5517,5518],{"class":1232},"generate_signature",[1098,5520,1460],{"class":1133},[1098,5522,5523,5526,5528,5530,5532],{"class":1100,"line":1675},[1098,5524,5525],{"class":1232},"            service_name",[1098,5527,1134],{"class":1133},[1098,5529,5299],{"class":1232},[1098,5531,1134],{"class":1133},[1098,5533,5534],{"class":1232}," service_token\n",[1098,5536,5537],{"class":1100,"line":1680},[1098,5538,2070],{"class":1133},[1098,5540,5541],{"class":1100,"line":1695},[1098,5542,1395],{"class":1115},[1098,5544,5545,5547,5549,5552,5554,5557,5559,5562,5564,5567],{"class":1100,"line":1714},[1098,5546,1348],{"class":1111},[1098,5548,1352],{"class":1351},[1098,5550,5551],{"class":1115}," hmac",[1098,5553,1148],{"class":1133},[1098,5555,5556],{"class":1232},"compare_digest",[1098,5558,1255],{"class":1133},[1098,5560,5561],{"class":1232},"signature",[1098,5563,1134],{"class":1133},[1098,5565,5566],{"class":1232}," expected_signature",[1098,5568,1262],{"class":1133},[1098,5570,5571,5573,5575,5577,5579,5582,5584],{"class":1100,"line":1728},[1098,5572,1698],{"class":1111},[1098,5574,1566],{"class":1232},[1098,5576,1255],{"class":1133},[1098,5578,1333],{"class":1332},[1098,5580,5581],{"class":1336},"Invalid signature",[1098,5583,1333],{"class":1332},[1098,5585,1342],{"class":1133},[1098,5587,5588],{"class":1100,"line":1746},[1098,5589,1395],{"class":1115},[1098,5591,5592],{"class":1100,"line":1760},[1098,5593,5594],{"class":1104},"        # Create service user object\n",[1098,5596,5597,5600,5602,5605,5607,5609],{"class":1100,"line":1778},[1098,5598,5599],{"class":1115},"        service_user ",[1098,5601,1229],{"class":1133},[1098,5603,5604],{"class":1232}," ServiceUser",[1098,5606,1255],{"class":1133},[1098,5608,5476],{"class":1232},[1098,5610,1342],{"class":1133},[1098,5612,5613],{"class":1100,"line":1783},[1098,5614,1395],{"class":1115},[1098,5616,5617,5619,5621,5624,5626,5629],{"class":1100,"line":1793},[1098,5618,2016],{"class":1111},[1098,5620,1662],{"class":1133},[1098,5622,5623],{"class":1115},"service_user",[1098,5625,1134],{"class":1133},[1098,5627,5628],{"class":1115}," service_token",[1098,5630,1342],{"class":1133},[1098,5632,5633],{"class":1100,"line":1803},[1098,5634,1282],{"class":1115},[1098,5636,5637,5639,5642,5644,5646,5648,5650,5652,5654,5656,5658],{"class":1100,"line":1808},[1098,5638,1288],{"class":1247},[1098,5640,5641],{"class":1291}," generate_signature",[1098,5643,1255],{"class":1133},[1098,5645,1298],{"class":1297},[1098,5647,1134],{"class":1133},[1098,5649,5294],{"class":1303},[1098,5651,1134],{"class":1133},[1098,5653,5299],{"class":1303},[1098,5655,1134],{"class":1133},[1098,5657,5628],{"class":1303},[1098,5659,1262],{"class":1133},[1098,5661,5662,5664,5667],{"class":1100,"line":1818},[1098,5663,1835],{"class":1268},[1098,5665,5666],{"class":1272},"Generate HMAC signature",[1098,5668,1276],{"class":1268},[1098,5670,5671,5674,5676,5678,5681,5683,5685,5687,5689,5691,5693,5695,5697,5699,5701,5703],{"class":1100,"line":1832},[1098,5672,5673],{"class":1115},"        message ",[1098,5675,1229],{"class":1133},[1098,5677,3867],{"class":1247},[1098,5679,5680],{"class":1336},"\"",[1098,5682,3874],{"class":3873},[1098,5684,5476],{"class":1115},[1098,5686,3879],{"class":3873},[1098,5688,1864],{"class":1336},[1098,5690,3874],{"class":3873},[1098,5692,5343],{"class":1115},[1098,5694,3879],{"class":3873},[1098,5696,1864],{"class":1336},[1098,5698,3874],{"class":3873},[1098,5700,5289],{"class":1115},[1098,5702,3879],{"class":3873},[1098,5704,5705],{"class":1336},"\"\n",[1098,5707,5708],{"class":1100,"line":1843},[1098,5709,1395],{"class":1115},[1098,5711,5712,5714,5716,5718,5721],{"class":1100,"line":1854},[1098,5713,2016],{"class":1111},[1098,5715,5551],{"class":1115},[1098,5717,1148],{"class":1133},[1098,5719,5720],{"class":1232},"new",[1098,5722,1460],{"class":1133},[1098,5724,5725,5727,5729,5732,5734,5736],{"class":1100,"line":1876},[1098,5726,2041],{"class":1232},[1098,5728,1148],{"class":1133},[1098,5730,5731],{"class":1321},"SERVICE_SECRET_KEY",[1098,5733,1148],{"class":1133},[1098,5735,2023],{"class":1232},[1098,5737,1979],{"class":1133},[1098,5739,5740,5743,5745,5747],{"class":1100,"line":1896},[1098,5741,5742],{"class":1232},"            message",[1098,5744,1148],{"class":1133},[1098,5746,2023],{"class":1232},[1098,5748,1979],{"class":1133},[1098,5750,5751,5754,5756],{"class":1100,"line":1916},[1098,5752,5753],{"class":1232},"            hashlib",[1098,5755,1148],{"class":1133},[1098,5757,5758],{"class":1598},"sha256\n",[1098,5760,5761,5764,5767],{"class":1100,"line":1961},[1098,5762,5763],{"class":1133},"        ).",[1098,5765,5766],{"class":1232},"hexdigest",[1098,5768,1236],{"class":1133},[1098,5770,5771],{"class":1100,"line":1982},[1098,5772,1220],{"emptyLinePlaceholder":1219},[1098,5774,5775,5777,5779],{"class":1100,"line":2002},[1098,5776,1248],{"class":1247},[1098,5778,5604],{"class":1251},[1098,5780,1441],{"class":1133},[1098,5782,5783,5785,5788],{"class":1100,"line":2008},[1098,5784,1269],{"class":1268},[1098,5786,5787],{"class":1272},"Represents a service user for authentication",[1098,5789,1276],{"class":1268},[1098,5791,5792],{"class":1100,"line":2013},[1098,5793,1282],{"class":1115},[1098,5795,5796,5798,5801,5803,5805,5807,5809],{"class":1100,"line":2028},[1098,5797,1288],{"class":1247},[1098,5799,5800],{"class":4766}," __init__",[1098,5802,1255],{"class":1133},[1098,5804,1298],{"class":1297},[1098,5806,1134],{"class":1133},[1098,5808,5294],{"class":1303},[1098,5810,1262],{"class":1133},[1098,5812,5813,5816,5818,5820,5823],{"class":1100,"line":2038},[1098,5814,5815],{"class":3697},"        self",[1098,5817,1148],{"class":1133},[1098,5819,5476],{"class":1598},[1098,5821,5822],{"class":1133}," =",[1098,5824,5825],{"class":1115}," service_name\n",[1098,5827,5828,5830,5832,5834,5836],{"class":1100,"line":2052},[1098,5829,5815],{"class":3697},[1098,5831,1148],{"class":1133},[1098,5833,4377],{"class":1598},[1098,5835,5822],{"class":1133},[1098,5837,4208],{"class":1388},[1098,5839,5840,5842,5844,5847,5849],{"class":1100,"line":2067},[1098,5841,5815],{"class":3697},[1098,5843,1148],{"class":1133},[1098,5845,5846],{"class":1598},"is_service",[1098,5848,5822],{"class":1133},[1098,5850,4208],{"class":1388},[1098,5852,5853],{"class":1100,"line":2073},[1098,5854,1282],{"class":1115},[1098,5856,5857,5859],{"class":1100,"line":2078},[1098,5858,1811],{"class":1133},[1098,5860,5861],{"class":1814},"property\n",[1098,5863,5864,5866,5869,5871,5873],{"class":1100,"line":2085},[1098,5865,1288],{"class":1247},[1098,5867,5868],{"class":1291}," is_anonymous",[1098,5870,1255],{"class":1133},[1098,5872,1298],{"class":1297},[1098,5874,1262],{"class":1133},[1098,5876,5877,5879],{"class":1100,"line":2099},[1098,5878,2016],{"class":1111},[1098,5880,4386],{"class":1388},[1098,5882,5883],{"class":1100,"line":2109},[1098,5884,1220],{"emptyLinePlaceholder":1219},[1098,5886,5887,5889,5892],{"class":1100,"line":2118},[1098,5888,1248],{"class":1247},[1098,5890,5891],{"class":1251}," ServiceClient",[1098,5893,1441],{"class":1133},[1098,5895,5896,5898,5901],{"class":1100,"line":2137},[1098,5897,1269],{"class":1268},[1098,5899,5900],{"class":1272},"Client for making authenticated service calls",[1098,5902,1276],{"class":1268},[1098,5904,5905],{"class":1100,"line":2176},[1098,5906,1282],{"class":1115},[1098,5908,5909,5911,5913,5915,5917,5919,5921],{"class":1100,"line":2195},[1098,5910,1288],{"class":1247},[1098,5912,5800],{"class":4766},[1098,5914,1255],{"class":1133},[1098,5916,1298],{"class":1297},[1098,5918,1134],{"class":1133},[1098,5920,5294],{"class":1303},[1098,5922,1262],{"class":1133},[1098,5924,5925,5927,5929,5931,5933],{"class":1100,"line":2213},[1098,5926,5815],{"class":3697},[1098,5928,1148],{"class":1133},[1098,5930,5476],{"class":1598},[1098,5932,5822],{"class":1133},[1098,5934,5825],{"class":1115},[1098,5936,5937,5939,5941,5943,5945,5947,5949,5951,5953,5955],{"class":1100,"line":2218},[1098,5938,5815],{"class":3697},[1098,5940,1148],{"class":1133},[1098,5942,5289],{"class":1598},[1098,5944,5822],{"class":1133},[1098,5946,5462],{"class":1115},[1098,5948,1148],{"class":1133},[1098,5950,5467],{"class":1321},[1098,5952,3327],{"class":1133},[1098,5954,5476],{"class":1115},[1098,5956,1427],{"class":1133},[1098,5958,5959],{"class":1100,"line":2223},[1098,5960,1282],{"class":1115},[1098,5962,5963,5965,5968,5970,5972,5974,5977,5979,5982,5984,5987,5990],{"class":1100,"line":2236},[1098,5964,1288],{"class":1247},[1098,5966,5967],{"class":1291}," make_request",[1098,5969,1255],{"class":1133},[1098,5971,1298],{"class":1297},[1098,5973,1134],{"class":1133},[1098,5975,5976],{"class":1303}," method",[1098,5978,1134],{"class":1133},[1098,5980,5981],{"class":1303}," url",[1098,5983,1134],{"class":1133},[1098,5985,5986],{"class":1351}," **",[1098,5988,5989],{"class":1303},"kwargs",[1098,5991,1262],{"class":1133},[1098,5993,5994,5996,5999],{"class":1100,"line":2245},[1098,5995,1835],{"class":1268},[1098,5997,5998],{"class":1272},"Make authenticated request to another service",[1098,6000,1276],{"class":1268},[1098,6002,6003,6005,6007,6009,6011,6013,6015,6017],{"class":1100,"line":2258},[1098,6004,5220],{"class":1115},[1098,6006,1229],{"class":1133},[1098,6008,3453],{"class":1814},[1098,6010,1255],{"class":1133},[1098,6012,5360],{"class":1232},[1098,6014,1148],{"class":1133},[1098,6016,5360],{"class":1232},[1098,6018,6019],{"class":1133},"())\n",[1098,6021,6022,6024,6026,6028,6030,6032,6034,6036],{"class":1100,"line":2271},[1098,6023,5248],{"class":1115},[1098,6025,1229],{"class":1133},[1098,6027,3698],{"class":3697},[1098,6029,1148],{"class":1133},[1098,6031,5518],{"class":1232},[1098,6033,1255],{"class":1133},[1098,6035,5343],{"class":1232},[1098,6037,1342],{"class":1133},[1098,6039,6040],{"class":1100,"line":2276},[1098,6041,1395],{"class":1115},[1098,6043,6044,6047,6049,6052,6054,6056,6058,6060,6063,6065,6067],{"class":1100,"line":2281},[1098,6045,6046],{"class":1115},"        headers ",[1098,6048,1229],{"class":1133},[1098,6050,6051],{"class":1115}," kwargs",[1098,6053,1148],{"class":1133},[1098,6055,1327],{"class":1232},[1098,6057,1255],{"class":1133},[1098,6059,1333],{"class":1332},[1098,6061,6062],{"class":1336},"headers",[1098,6064,1333],{"class":1332},[1098,6066,1134],{"class":1133},[1098,6068,6069],{"class":1133}," {})\n",[1098,6071,6072,6075,6077,6079],{"class":1100,"line":2288},[1098,6073,6074],{"class":1115},"        headers",[1098,6076,1148],{"class":1133},[1098,6078,4948],{"class":1232},[1098,6080,2989],{"class":1133},[1098,6082,6083,6085,6088,6090,6092,6094,6096,6098],{"class":1100,"line":2316},[1098,6084,1857],{"class":1332},[1098,6086,6087],{"class":1336},"X-Service-Token",[1098,6089,1333],{"class":1332},[1098,6091,1864],{"class":1133},[1098,6093,3698],{"class":3697},[1098,6095,1148],{"class":1133},[1098,6097,5289],{"class":1598},[1098,6099,1873],{"class":1133},[1098,6101,6102,6104,6107,6109,6111,6113,6115,6118],{"class":1100,"line":2326},[1098,6103,1857],{"class":1332},[1098,6105,6106],{"class":1336},"X-Service-Name",[1098,6108,1333],{"class":1332},[1098,6110,1864],{"class":1133},[1098,6112,5462],{"class":1232},[1098,6114,1148],{"class":1133},[1098,6116,6117],{"class":1321},"SERVICE_NAME",[1098,6119,1873],{"class":1133},[1098,6121,6122,6124,6127,6129,6131,6133],{"class":1100,"line":2333},[1098,6123,1857],{"class":1332},[1098,6125,6126],{"class":1336},"X-Timestamp",[1098,6128,1333],{"class":1332},[1098,6130,1864],{"class":1133},[1098,6132,5299],{"class":1232},[1098,6134,1873],{"class":1133},[1098,6136,6137,6139,6142,6144,6146],{"class":1100,"line":2348},[1098,6138,1857],{"class":1332},[1098,6140,6141],{"class":1336},"X-Signature",[1098,6143,1333],{"class":1332},[1098,6145,1864],{"class":1133},[1098,6147,6148],{"class":1232}," signature\n",[1098,6150,6151],{"class":1100,"line":2357},[1098,6152,3394],{"class":1133},[1098,6154,6155,6158,6160,6162,6164,6166,6169,6171],{"class":1100,"line":2370},[1098,6156,6157],{"class":1115},"        kwargs",[1098,6159,3327],{"class":1133},[1098,6161,1333],{"class":1332},[1098,6163,6062],{"class":1336},[1098,6165,1333],{"class":1332},[1098,6167,6168],{"class":1133},"]",[1098,6170,5822],{"class":1133},[1098,6172,6173],{"class":1115}," headers\n",[1098,6175,6176],{"class":1100,"line":2385},[1098,6177,1395],{"class":1115},[1098,6179,6180,6182,6184,6186,6188,6190,6193,6195,6197,6199,6201,6203],{"class":1100,"line":2390},[1098,6181,2016],{"class":1111},[1098,6183,3830],{"class":1115},[1098,6185,1148],{"class":1133},[1098,6187,2677],{"class":1232},[1098,6189,1255],{"class":1133},[1098,6191,6192],{"class":1232},"method",[1098,6194,1134],{"class":1133},[1098,6196,5981],{"class":1232},[1098,6198,1134],{"class":1133},[1098,6200,5986],{"class":1351},[1098,6202,5989],{"class":1232},[1098,6204,1342],{"class":1133},[1098,6206,6207],{"class":1100,"line":2395},[1098,6208,1282],{"class":1115},[1098,6210,6211,6213,6215,6217,6219,6221,6223],{"class":1100,"line":2424},[1098,6212,1288],{"class":1247},[1098,6214,5641],{"class":1291},[1098,6216,1255],{"class":1133},[1098,6218,1298],{"class":1297},[1098,6220,1134],{"class":1133},[1098,6222,5299],{"class":1303},[1098,6224,1262],{"class":1133},[1098,6226,6227,6229,6232],{"class":1100,"line":2446},[1098,6228,1835],{"class":1268},[1098,6230,6231],{"class":1272},"Generate request signature",[1098,6233,1276],{"class":1268},[1098,6235,6236,6238,6240,6242,6244,6246,6248,6250,6252,6254,6256,6258,6260,6262,6264,6266,6268,6270,6272,6274],{"class":1100,"line":2451},[1098,6237,5673],{"class":1115},[1098,6239,1229],{"class":1133},[1098,6241,3867],{"class":1247},[1098,6243,5680],{"class":1336},[1098,6245,3874],{"class":3873},[1098,6247,1499],{"class":1115},[1098,6249,1148],{"class":1133},[1098,6251,6117],{"class":1321},[1098,6253,3879],{"class":3873},[1098,6255,1864],{"class":1336},[1098,6257,3874],{"class":3873},[1098,6259,5343],{"class":1115},[1098,6261,3879],{"class":3873},[1098,6263,1864],{"class":1336},[1098,6265,3874],{"class":3873},[1098,6267,1298],{"class":3697},[1098,6269,1148],{"class":1133},[1098,6271,5289],{"class":1598},[1098,6273,3879],{"class":3873},[1098,6275,5705],{"class":1336},[1098,6277,6278],{"class":1100,"line":2459},[1098,6279,1395],{"class":1115},[1098,6281,6282,6284,6286,6288,6290],{"class":1100,"line":2464},[1098,6283,2016],{"class":1111},[1098,6285,5551],{"class":1115},[1098,6287,1148],{"class":1133},[1098,6289,5720],{"class":1232},[1098,6291,1460],{"class":1133},[1098,6293,6294,6296,6298,6300,6302,6304],{"class":1100,"line":2477},[1098,6295,2041],{"class":1232},[1098,6297,1148],{"class":1133},[1098,6299,5731],{"class":1321},[1098,6301,1148],{"class":1133},[1098,6303,2023],{"class":1232},[1098,6305,1979],{"class":1133},[1098,6307,6308,6310,6312,6314],{"class":1100,"line":2494},[1098,6309,5742],{"class":1232},[1098,6311,1148],{"class":1133},[1098,6313,2023],{"class":1232},[1098,6315,1979],{"class":1133},[1098,6317,6318,6320,6322],{"class":1100,"line":2507},[1098,6319,5753],{"class":1232},[1098,6321,1148],{"class":1133},[1098,6323,5758],{"class":1598},[1098,6325,6326,6328,6330],{"class":1100,"line":2524},[1098,6327,5763],{"class":1133},[1098,6329,5766],{"class":1232},[1098,6331,1236],{"class":1133},[1035,6333,6335],{"id":6334},"_2-mtls-mutual-tls","2. mTLS (Mutual TLS)",[1088,6337,6339],{"className":1090,"code":6338,"language":1092,"meta":1093,"style":1093},"# mtls.py\nimport ssl\nimport requests\nfrom django.conf import settings\n\nclass MTLSClient:\n    \"\"\"Client for mTLS communication\"\"\"\n    \n    def __init__(self):\n        self.cert_file = settings.MTLS_CERT_FILE\n        self.key_file = settings.MTLS_KEY_FILE\n        self.ca_file = settings.MTLS_CA_FILE\n    \n    def make_request(self, method, url, **kwargs):\n        \"\"\"Make mTLS authenticated request\"\"\"\n        # Configure SSL context\n        ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)\n        ssl_context.load_cert_chain(self.cert_file, self.key_file)\n        ssl_context.load_verify_locations(self.ca_file)\n        ssl_context.check_hostname = True\n        ssl_context.verify_mode = ssl.CERT_REQUIRED\n        \n        # Create session with SSL context\n        session = requests.Session()\n        session.mount('https://', requests.adapters.HTTPAdapter())\n        \n        # Make request with client certificate\n        kwargs['cert'] = (self.cert_file, self.key_file)\n        kwargs['verify'] = self.ca_file\n        \n        return session.request(method, url, **kwargs)\n\n# Django middleware for mTLS\nclass MTLSMiddleware:\n    \"\"\"Middleware to verify client certificates\"\"\"\n    \n    def __init__(self, get_response):\n        self.get_response = get_response\n    \n    def __call__(self, request):\n        # Verify client certificate\n        if not self.verify_client_cert(request):\n            return HttpResponseForbidden('Invalid client certificate')\n        \n        response = self.get_response(request)\n        return response\n    \n    def verify_client_cert(self, request):\n        \"\"\"Verify client certificate\"\"\"\n        # In production, this would be handled by the web server\n        # This is a simplified example\n        \n        cert_header = request.META.get('HTTP_X_CLIENT_CERT')\n        if not cert_header:\n            return False\n        \n        # Verify certificate against CA\n        # Implementation depends on your certificate infrastructure\n        \n        return True\n",[1095,6340,6341,6346,6353,6359,6373,6377,6386,6395,6399,6411,6429,6447,6465,6469,6495,6504,6509,6541,6569,6588,6601,6619,6623,6628,6644,6679,6683,6688,6723,6747,6751,6778,6782,6787,6796,6805,6809,6826,6840,6844,6861,6866,6885,6903,6907,6926,6933,6937,6954,6963,6968,6973,6977,7005,7016,7022,7026,7031,7036,7040],{"__ignoreMap":1093},[1098,6342,6343],{"class":1100,"line":1101},[1098,6344,6345],{"class":1104},"# mtls.py\n",[1098,6347,6348,6350],{"class":1100,"line":1108},[1098,6349,1112],{"class":1111},[1098,6351,6352],{"class":1115}," ssl\n",[1098,6354,6355,6357],{"class":1100,"line":1119},[1098,6356,1112],{"class":1111},[1098,6358,3502],{"class":1115},[1098,6360,6361,6363,6365,6367,6369,6371],{"class":1100,"line":1140},[1098,6362,1122],{"class":1111},[1098,6364,1145],{"class":1115},[1098,6366,1148],{"class":1133},[1098,6368,1151],{"class":1115},[1098,6370,1112],{"class":1111},[1098,6372,1156],{"class":1115},[1098,6374,6375],{"class":1100,"line":1159},[1098,6376,1220],{"emptyLinePlaceholder":1219},[1098,6378,6379,6381,6384],{"class":1100,"line":1181},[1098,6380,1248],{"class":1247},[1098,6382,6383],{"class":1251}," MTLSClient",[1098,6385,1441],{"class":1133},[1098,6387,6388,6390,6393],{"class":1100,"line":1199},[1098,6389,1269],{"class":1268},[1098,6391,6392],{"class":1272},"Client for mTLS communication",[1098,6394,1276],{"class":1268},[1098,6396,6397],{"class":1100,"line":1216},[1098,6398,1282],{"class":1115},[1098,6400,6401,6403,6405,6407,6409],{"class":1100,"line":1223},[1098,6402,1288],{"class":1247},[1098,6404,5800],{"class":4766},[1098,6406,1255],{"class":1133},[1098,6408,1298],{"class":1297},[1098,6410,1262],{"class":1133},[1098,6412,6413,6415,6417,6420,6422,6424,6426],{"class":1100,"line":1239},[1098,6414,5815],{"class":3697},[1098,6416,1148],{"class":1133},[1098,6418,6419],{"class":1598},"cert_file",[1098,6421,5822],{"class":1133},[1098,6423,5462],{"class":1115},[1098,6425,1148],{"class":1133},[1098,6427,6428],{"class":1321},"MTLS_CERT_FILE\n",[1098,6430,6431,6433,6435,6438,6440,6442,6444],{"class":1100,"line":1244},[1098,6432,5815],{"class":3697},[1098,6434,1148],{"class":1133},[1098,6436,6437],{"class":1598},"key_file",[1098,6439,5822],{"class":1133},[1098,6441,5462],{"class":1115},[1098,6443,1148],{"class":1133},[1098,6445,6446],{"class":1321},"MTLS_KEY_FILE\n",[1098,6448,6449,6451,6453,6456,6458,6460,6462],{"class":1100,"line":1265},[1098,6450,5815],{"class":3697},[1098,6452,1148],{"class":1133},[1098,6454,6455],{"class":1598},"ca_file",[1098,6457,5822],{"class":1133},[1098,6459,5462],{"class":1115},[1098,6461,1148],{"class":1133},[1098,6463,6464],{"class":1321},"MTLS_CA_FILE\n",[1098,6466,6467],{"class":1100,"line":1279},[1098,6468,1282],{"class":1115},[1098,6470,6471,6473,6475,6477,6479,6481,6483,6485,6487,6489,6491,6493],{"class":1100,"line":1285},[1098,6472,1288],{"class":1247},[1098,6474,5967],{"class":1291},[1098,6476,1255],{"class":1133},[1098,6478,1298],{"class":1297},[1098,6480,1134],{"class":1133},[1098,6482,5976],{"class":1303},[1098,6484,1134],{"class":1133},[1098,6486,5981],{"class":1303},[1098,6488,1134],{"class":1133},[1098,6490,5986],{"class":1351},[1098,6492,5989],{"class":1303},[1098,6494,1262],{"class":1133},[1098,6496,6497,6499,6502],{"class":1100,"line":1309},[1098,6498,1835],{"class":1268},[1098,6500,6501],{"class":1272},"Make mTLS authenticated request",[1098,6503,1276],{"class":1268},[1098,6505,6506],{"class":1100,"line":1345},[1098,6507,6508],{"class":1104},"        # Configure SSL context\n",[1098,6510,6511,6514,6516,6519,6521,6524,6526,6529,6531,6534,6536,6539],{"class":1100,"line":1382},[1098,6512,6513],{"class":1115},"        ssl_context ",[1098,6515,1229],{"class":1133},[1098,6517,6518],{"class":1115}," ssl",[1098,6520,1148],{"class":1133},[1098,6522,6523],{"class":1232},"create_default_context",[1098,6525,1255],{"class":1133},[1098,6527,6528],{"class":1232},"ssl",[1098,6530,1148],{"class":1133},[1098,6532,6533],{"class":1598},"Purpose",[1098,6535,1148],{"class":1133},[1098,6537,6538],{"class":1321},"SERVER_AUTH",[1098,6540,1342],{"class":1133},[1098,6542,6543,6546,6548,6551,6553,6555,6557,6559,6561,6563,6565,6567],{"class":1100,"line":1392},[1098,6544,6545],{"class":1115},"        ssl_context",[1098,6547,1148],{"class":1133},[1098,6549,6550],{"class":1232},"load_cert_chain",[1098,6552,1255],{"class":1133},[1098,6554,1298],{"class":3697},[1098,6556,1148],{"class":1133},[1098,6558,6419],{"class":1598},[1098,6560,1134],{"class":1133},[1098,6562,3698],{"class":3697},[1098,6564,1148],{"class":1133},[1098,6566,6437],{"class":1598},[1098,6568,1342],{"class":1133},[1098,6570,6571,6573,6575,6578,6580,6582,6584,6586],{"class":1100,"line":1398},[1098,6572,6545],{"class":1115},[1098,6574,1148],{"class":1133},[1098,6576,6577],{"class":1232},"load_verify_locations",[1098,6579,1255],{"class":1133},[1098,6581,1298],{"class":3697},[1098,6583,1148],{"class":1133},[1098,6585,6455],{"class":1598},[1098,6587,1342],{"class":1133},[1098,6589,6590,6592,6594,6597,6599],{"class":1100,"line":1430},[1098,6591,6545],{"class":1115},[1098,6593,1148],{"class":1133},[1098,6595,6596],{"class":1598},"check_hostname",[1098,6598,5822],{"class":1133},[1098,6600,4208],{"class":1388},[1098,6602,6603,6605,6607,6610,6612,6614,6616],{"class":1100,"line":1435},[1098,6604,6545],{"class":1115},[1098,6606,1148],{"class":1133},[1098,6608,6609],{"class":1598},"verify_mode",[1098,6611,5822],{"class":1133},[1098,6613,6518],{"class":1115},[1098,6615,1148],{"class":1133},[1098,6617,6618],{"class":1321},"CERT_REQUIRED\n",[1098,6620,6621],{"class":1100,"line":1444},[1098,6622,1395],{"class":1115},[1098,6624,6625],{"class":1100,"line":1463},[1098,6626,6627],{"class":1104},"        # Create session with SSL context\n",[1098,6629,6630,6633,6635,6637,6639,6642],{"class":1100,"line":1474},[1098,6631,6632],{"class":1115},"        session ",[1098,6634,1229],{"class":1133},[1098,6636,3830],{"class":1115},[1098,6638,1148],{"class":1133},[1098,6640,6641],{"class":1232},"Session",[1098,6643,1236],{"class":1133},[1098,6645,6646,6649,6651,6654,6656,6658,6661,6663,6665,6667,6669,6672,6674,6677],{"class":1100,"line":1489},[1098,6647,6648],{"class":1115},"        session",[1098,6650,1148],{"class":1133},[1098,6652,6653],{"class":1232},"mount",[1098,6655,1255],{"class":1133},[1098,6657,1333],{"class":1332},[1098,6659,6660],{"class":1336},"https://",[1098,6662,1333],{"class":1332},[1098,6664,1134],{"class":1133},[1098,6666,3830],{"class":1232},[1098,6668,1148],{"class":1133},[1098,6670,6671],{"class":1598},"adapters",[1098,6673,1148],{"class":1133},[1098,6675,6676],{"class":1232},"HTTPAdapter",[1098,6678,6019],{"class":1133},[1098,6680,6681],{"class":1100,"line":1509},[1098,6682,1395],{"class":1115},[1098,6684,6685],{"class":1100,"line":1515},[1098,6686,6687],{"class":1104},"        # Make request with client certificate\n",[1098,6689,6690,6692,6694,6696,6699,6701,6703,6705,6707,6709,6711,6713,6715,6717,6719,6721],{"class":1100,"line":1521},[1098,6691,6157],{"class":1115},[1098,6693,3327],{"class":1133},[1098,6695,1333],{"class":1332},[1098,6697,6698],{"class":1336},"cert",[1098,6700,1333],{"class":1332},[1098,6702,6168],{"class":1133},[1098,6704,5822],{"class":1133},[1098,6706,1662],{"class":1133},[1098,6708,1298],{"class":3697},[1098,6710,1148],{"class":1133},[1098,6712,6419],{"class":1598},[1098,6714,1134],{"class":1133},[1098,6716,3698],{"class":3697},[1098,6718,1148],{"class":1133},[1098,6720,6437],{"class":1598},[1098,6722,1342],{"class":1133},[1098,6724,6725,6727,6729,6731,6734,6736,6738,6740,6742,6744],{"class":1100,"line":1547},[1098,6726,6157],{"class":1115},[1098,6728,3327],{"class":1133},[1098,6730,1333],{"class":1332},[1098,6732,6733],{"class":1336},"verify",[1098,6735,1333],{"class":1332},[1098,6737,6168],{"class":1133},[1098,6739,5822],{"class":1133},[1098,6741,3698],{"class":3697},[1098,6743,1148],{"class":1133},[1098,6745,6746],{"class":1598},"ca_file\n",[1098,6748,6749],{"class":1100,"line":1560},[1098,6750,1395],{"class":1115},[1098,6752,6753,6755,6758,6760,6762,6764,6766,6768,6770,6772,6774,6776],{"class":1100,"line":1580},[1098,6754,2016],{"class":1111},[1098,6756,6757],{"class":1115}," session",[1098,6759,1148],{"class":1133},[1098,6761,2677],{"class":1232},[1098,6763,1255],{"class":1133},[1098,6765,6192],{"class":1232},[1098,6767,1134],{"class":1133},[1098,6769,5981],{"class":1232},[1098,6771,1134],{"class":1133},[1098,6773,5986],{"class":1351},[1098,6775,5989],{"class":1232},[1098,6777,1342],{"class":1133},[1098,6779,6780],{"class":1100,"line":1585},[1098,6781,1220],{"emptyLinePlaceholder":1219},[1098,6783,6784],{"class":1100,"line":1617},[1098,6785,6786],{"class":1104},"# Django middleware for mTLS\n",[1098,6788,6789,6791,6794],{"class":1100,"line":1634},[1098,6790,1248],{"class":1247},[1098,6792,6793],{"class":1251}," MTLSMiddleware",[1098,6795,1441],{"class":1133},[1098,6797,6798,6800,6803],{"class":1100,"line":1652},[1098,6799,1269],{"class":1268},[1098,6801,6802],{"class":1272},"Middleware to verify client certificates",[1098,6804,1276],{"class":1268},[1098,6806,6807],{"class":1100,"line":1657},[1098,6808,1282],{"class":1115},[1098,6810,6811,6813,6815,6817,6819,6821,6824],{"class":1100,"line":1675},[1098,6812,1288],{"class":1247},[1098,6814,5800],{"class":4766},[1098,6816,1255],{"class":1133},[1098,6818,1298],{"class":1297},[1098,6820,1134],{"class":1133},[1098,6822,6823],{"class":1303}," get_response",[1098,6825,1262],{"class":1133},[1098,6827,6828,6830,6832,6835,6837],{"class":1100,"line":1680},[1098,6829,5815],{"class":3697},[1098,6831,1148],{"class":1133},[1098,6833,6834],{"class":1598},"get_response",[1098,6836,5822],{"class":1133},[1098,6838,6839],{"class":1115}," get_response\n",[1098,6841,6842],{"class":1100,"line":1695},[1098,6843,1282],{"class":1115},[1098,6845,6846,6848,6851,6853,6855,6857,6859],{"class":1100,"line":1714},[1098,6847,1288],{"class":1247},[1098,6849,6850],{"class":4766}," __call__",[1098,6852,1255],{"class":1133},[1098,6854,1298],{"class":1297},[1098,6856,1134],{"class":1133},[1098,6858,1304],{"class":1303},[1098,6860,1262],{"class":1133},[1098,6862,6863],{"class":1100,"line":1728},[1098,6864,6865],{"class":1104},"        # Verify client certificate\n",[1098,6867,6868,6870,6872,6874,6876,6879,6881,6883],{"class":1100,"line":1746},[1098,6869,1348],{"class":1111},[1098,6871,1352],{"class":1351},[1098,6873,3698],{"class":3697},[1098,6875,1148],{"class":1133},[1098,6877,6878],{"class":1232},"verify_client_cert",[1098,6880,1255],{"class":1133},[1098,6882,2677],{"class":1232},[1098,6884,1262],{"class":1133},[1098,6886,6887,6889,6892,6894,6896,6899,6901],{"class":1100,"line":1760},[1098,6888,1385],{"class":1111},[1098,6890,6891],{"class":1232}," HttpResponseForbidden",[1098,6893,1255],{"class":1133},[1098,6895,1333],{"class":1332},[1098,6897,6898],{"class":1336},"Invalid client certificate",[1098,6900,1333],{"class":1332},[1098,6902,1342],{"class":1133},[1098,6904,6905],{"class":1100,"line":1778},[1098,6906,1395],{"class":1115},[1098,6908,6909,6912,6914,6916,6918,6920,6922,6924],{"class":1100,"line":1783},[1098,6910,6911],{"class":1115},"        response ",[1098,6913,1229],{"class":1133},[1098,6915,3698],{"class":3697},[1098,6917,1148],{"class":1133},[1098,6919,6834],{"class":1232},[1098,6921,1255],{"class":1133},[1098,6923,2677],{"class":1232},[1098,6925,1342],{"class":1133},[1098,6927,6928,6930],{"class":1100,"line":1793},[1098,6929,2016],{"class":1111},[1098,6931,6932],{"class":1115}," response\n",[1098,6934,6935],{"class":1100,"line":1803},[1098,6936,1282],{"class":1115},[1098,6938,6939,6941,6944,6946,6948,6950,6952],{"class":1100,"line":1808},[1098,6940,1288],{"class":1247},[1098,6942,6943],{"class":1291}," verify_client_cert",[1098,6945,1255],{"class":1133},[1098,6947,1298],{"class":1297},[1098,6949,1134],{"class":1133},[1098,6951,1304],{"class":1303},[1098,6953,1262],{"class":1133},[1098,6955,6956,6958,6961],{"class":1100,"line":1818},[1098,6957,1835],{"class":1268},[1098,6959,6960],{"class":1272},"Verify client certificate",[1098,6962,1276],{"class":1268},[1098,6964,6965],{"class":1100,"line":1832},[1098,6966,6967],{"class":1104},"        # In production, this would be handled by the web server\n",[1098,6969,6970],{"class":1100,"line":1843},[1098,6971,6972],{"class":1104},"        # This is a simplified example\n",[1098,6974,6975],{"class":1100,"line":1854},[1098,6976,1395],{"class":1115},[1098,6978,6979,6982,6984,6986,6988,6990,6992,6994,6996,6998,7001,7003],{"class":1100,"line":1876},[1098,6980,6981],{"class":1115},"        cert_header ",[1098,6983,1229],{"class":1133},[1098,6985,1304],{"class":1115},[1098,6987,1148],{"class":1133},[1098,6989,1322],{"class":1321},[1098,6991,1148],{"class":1133},[1098,6993,1327],{"class":1232},[1098,6995,1255],{"class":1133},[1098,6997,1333],{"class":1332},[1098,6999,7000],{"class":1336},"HTTP_X_CLIENT_CERT",[1098,7002,1333],{"class":1332},[1098,7004,1342],{"class":1133},[1098,7006,7007,7009,7011,7014],{"class":1100,"line":1896},[1098,7008,1348],{"class":1111},[1098,7010,1352],{"class":1351},[1098,7012,7013],{"class":1115}," cert_header",[1098,7015,1441],{"class":1133},[1098,7017,7018,7020],{"class":1100,"line":1916},[1098,7019,1385],{"class":1111},[1098,7021,4386],{"class":1388},[1098,7023,7024],{"class":1100,"line":1961},[1098,7025,1395],{"class":1115},[1098,7027,7028],{"class":1100,"line":1982},[1098,7029,7030],{"class":1104},"        # Verify certificate against CA\n",[1098,7032,7033],{"class":1100,"line":2002},[1098,7034,7035],{"class":1104},"        # Implementation depends on your certificate infrastructure\n",[1098,7037,7038],{"class":1100,"line":2008},[1098,7039,1395],{"class":1115},[1098,7041,7042,7044],{"class":1100,"line":2013},[1098,7043,2016],{"class":1111},[1098,7045,4208],{"class":1388},[1030,7047,1072],{"id":7048},"api-security",[1035,7050,7052],{"id":7051},"_1-rate-limiting-and-throttling","1. Rate Limiting and Throttling",[1088,7054,7056],{"className":1090,"code":7055,"language":1092,"meta":1093,"style":1093},"# throttling.py\nfrom rest_framework.throttling import UserRateThrottle, AnonRateThrottle\nfrom django.core.cache import cache\nimport time\n\nclass BurstRateThrottle(UserRateThrottle):\n    \"\"\"Burst rate limiting with sustained rate\"\"\"\n    \n    scope = 'burst'\n    \n    def allow_request(self, request, view):\n        if self.rate is None:\n            return True\n        \n        self.key = self.get_cache_key(request, view)\n        if self.key is None:\n            return True\n        \n        self.history = self.cache.get(self.key, [])\n        self.now = self.timer()\n        \n        # Drop any requests from the history which have now passed the throttle duration\n        while self.history and self.history[-1] \u003C= self.now - self.duration:\n            self.history.pop()\n        \n        if len(self.history) >= self.num_requests:\n            return self.throttle_failure()\n        \n        return self.throttle_success()\n\nclass IPRateThrottle(AnonRateThrottle):\n    \"\"\"IP-based rate limiting\"\"\"\n    \n    def get_cache_key(self, request, view):\n        if request.user.is_authenticated:\n            return None  # Only throttle anonymous requests\n        \n        return self.cache_format % {\n            'scope': self.scope,\n            'ident': self.get_ident(request)\n        }\n\nclass DynamicRateThrottle(UserRateThrottle):\n    \"\"\"Dynamic rate limiting based on user tier\"\"\"\n    \n    def get_rate(self):\n        \"\"\"Get rate based on user tier\"\"\"\n        if not hasattr(self, 'request') or not self.request.user.is_authenticated:\n            return '100/hour'\n        \n        user = self.request.user\n        \n        if user.groups.filter(name='premium').exists():\n            return '10000/hour'\n        elif user.groups.filter(name='pro').exists():\n            return '5000/hour'\n        else:\n            return '1000/hour'\n\n# Usage in views\nclass UserViewSet(ModelViewSet):\n    throttle_classes = [BurstRateThrottle, IPRateThrottle, DynamicRateThrottle]\n    throttle_scope = 'user'\n",[1095,7057,7058,7063,7084,7105,7111,7115,7129,7138,7142,7156,7160,7181,7200,7206,7210,7238,7254,7260,7264,7299,7319,7323,7328,7377,7393,7397,7426,7439,7443,7456,7460,7474,7483,7487,7508,7524,7533,7537,7553,7572,7596,7600,7604,7617,7626,7630,7643,7652,7694,7705,7709,7725,7729,7762,7773,7806,7817,7823,7834,7838,7842,7854,7876],{"__ignoreMap":1093},[1098,7059,7060],{"class":1100,"line":1101},[1098,7061,7062],{"class":1104},"# throttling.py\n",[1098,7064,7065,7067,7069,7071,7074,7076,7079,7081],{"class":1100,"line":1108},[1098,7066,1122],{"class":1111},[1098,7068,1186],{"class":1115},[1098,7070,1148],{"class":1133},[1098,7072,7073],{"class":1115},"throttling ",[1098,7075,1112],{"class":1111},[1098,7077,7078],{"class":1115}," UserRateThrottle",[1098,7080,1134],{"class":1133},[1098,7082,7083],{"class":1115}," AnonRateThrottle\n",[1098,7085,7086,7088,7090,7092,7095,7097,7100,7102],{"class":1100,"line":1119},[1098,7087,1122],{"class":1111},[1098,7089,1145],{"class":1115},[1098,7091,1148],{"class":1133},[1098,7093,7094],{"class":1115},"core",[1098,7096,1148],{"class":1133},[1098,7098,7099],{"class":1115},"cache ",[1098,7101,1112],{"class":1111},[1098,7103,7104],{"class":1115}," cache\n",[1098,7106,7107,7109],{"class":1100,"line":1140},[1098,7108,1112],{"class":1111},[1098,7110,5071],{"class":1115},[1098,7112,7113],{"class":1100,"line":1159},[1098,7114,1220],{"emptyLinePlaceholder":1219},[1098,7116,7117,7119,7122,7124,7127],{"class":1100,"line":1181},[1098,7118,1248],{"class":1247},[1098,7120,7121],{"class":1251}," BurstRateThrottle",[1098,7123,1255],{"class":1133},[1098,7125,7126],{"class":1258},"UserRateThrottle",[1098,7128,1262],{"class":1133},[1098,7130,7131,7133,7136],{"class":1100,"line":1199},[1098,7132,1269],{"class":1268},[1098,7134,7135],{"class":1272},"Burst rate limiting with sustained rate",[1098,7137,1276],{"class":1268},[1098,7139,7140],{"class":1100,"line":1216},[1098,7141,1282],{"class":1115},[1098,7143,7144,7147,7149,7151,7154],{"class":1100,"line":1223},[1098,7145,7146],{"class":1115},"    scope ",[1098,7148,1229],{"class":1133},[1098,7150,1417],{"class":1332},[1098,7152,7153],{"class":1336},"burst",[1098,7155,1999],{"class":1332},[1098,7157,7158],{"class":1100,"line":1239},[1098,7159,1282],{"class":1115},[1098,7161,7162,7164,7167,7169,7171,7173,7175,7177,7179],{"class":1100,"line":1244},[1098,7163,1288],{"class":1247},[1098,7165,7166],{"class":1291}," allow_request",[1098,7168,1255],{"class":1133},[1098,7170,1298],{"class":1297},[1098,7172,1134],{"class":1133},[1098,7174,1304],{"class":1303},[1098,7176,1134],{"class":1133},[1098,7178,4347],{"class":1303},[1098,7180,1262],{"class":1133},[1098,7182,7183,7185,7187,7189,7192,7195,7198],{"class":1100,"line":1265},[1098,7184,1348],{"class":1111},[1098,7186,3698],{"class":3697},[1098,7188,1148],{"class":1133},[1098,7190,7191],{"class":1598},"rate",[1098,7193,7194],{"class":1351}," is",[1098,7196,7197],{"class":1388}," None",[1098,7199,1441],{"class":1133},[1098,7201,7202,7204],{"class":1100,"line":1279},[1098,7203,1385],{"class":1111},[1098,7205,4208],{"class":1388},[1098,7207,7208],{"class":1100,"line":1285},[1098,7209,1395],{"class":1115},[1098,7211,7212,7214,7216,7219,7221,7223,7225,7228,7230,7232,7234,7236],{"class":1100,"line":1309},[1098,7213,5815],{"class":3697},[1098,7215,1148],{"class":1133},[1098,7217,7218],{"class":1598},"key",[1098,7220,5822],{"class":1133},[1098,7222,3698],{"class":3697},[1098,7224,1148],{"class":1133},[1098,7226,7227],{"class":1232},"get_cache_key",[1098,7229,1255],{"class":1133},[1098,7231,2677],{"class":1232},[1098,7233,1134],{"class":1133},[1098,7235,4347],{"class":1232},[1098,7237,1342],{"class":1133},[1098,7239,7240,7242,7244,7246,7248,7250,7252],{"class":1100,"line":1345},[1098,7241,1348],{"class":1111},[1098,7243,3698],{"class":3697},[1098,7245,1148],{"class":1133},[1098,7247,7218],{"class":1598},[1098,7249,7194],{"class":1351},[1098,7251,7197],{"class":1388},[1098,7253,1441],{"class":1133},[1098,7255,7256,7258],{"class":1100,"line":1382},[1098,7257,1385],{"class":1111},[1098,7259,4208],{"class":1388},[1098,7261,7262],{"class":1100,"line":1392},[1098,7263,1395],{"class":1115},[1098,7265,7266,7268,7270,7273,7275,7277,7279,7282,7284,7286,7288,7290,7292,7294,7296],{"class":1100,"line":1398},[1098,7267,5815],{"class":3697},[1098,7269,1148],{"class":1133},[1098,7271,7272],{"class":1598},"history",[1098,7274,5822],{"class":1133},[1098,7276,3698],{"class":3697},[1098,7278,1148],{"class":1133},[1098,7280,7281],{"class":1598},"cache",[1098,7283,1148],{"class":1133},[1098,7285,1327],{"class":1232},[1098,7287,1255],{"class":1133},[1098,7289,1298],{"class":3697},[1098,7291,1148],{"class":1133},[1098,7293,7218],{"class":1598},[1098,7295,1134],{"class":1133},[1098,7297,7298],{"class":1133}," [])\n",[1098,7300,7301,7303,7305,7308,7310,7312,7314,7317],{"class":1100,"line":1430},[1098,7302,5815],{"class":3697},[1098,7304,1148],{"class":1133},[1098,7306,7307],{"class":1598},"now",[1098,7309,5822],{"class":1133},[1098,7311,3698],{"class":3697},[1098,7313,1148],{"class":1133},[1098,7315,7316],{"class":1232},"timer",[1098,7318,1236],{"class":1133},[1098,7320,7321],{"class":1100,"line":1435},[1098,7322,1395],{"class":1115},[1098,7324,7325],{"class":1100,"line":1444},[1098,7326,7327],{"class":1104},"        # Drop any requests from the history which have now passed the throttle duration\n",[1098,7329,7330,7333,7335,7337,7339,7342,7344,7346,7348,7350,7352,7354,7356,7359,7361,7363,7365,7368,7370,7372,7375],{"class":1100,"line":1463},[1098,7331,7332],{"class":1111},"        while",[1098,7334,3698],{"class":3697},[1098,7336,1148],{"class":1133},[1098,7338,7272],{"class":1598},[1098,7340,7341],{"class":1351}," and",[1098,7343,3698],{"class":3697},[1098,7345,1148],{"class":1133},[1098,7347,7272],{"class":1598},[1098,7349,3327],{"class":1133},[1098,7351,5381],{"class":1351},[1098,7353,1424],{"class":1423},[1098,7355,6168],{"class":1133},[1098,7357,7358],{"class":1351}," \u003C=",[1098,7360,3698],{"class":3697},[1098,7362,1148],{"class":1133},[1098,7364,7307],{"class":1598},[1098,7366,7367],{"class":1351}," -",[1098,7369,3698],{"class":3697},[1098,7371,1148],{"class":1133},[1098,7373,7374],{"class":1598},"duration",[1098,7376,1441],{"class":1133},[1098,7378,7379,7382,7384,7386,7388,7391],{"class":1100,"line":1474},[1098,7380,7381],{"class":3697},"            self",[1098,7383,1148],{"class":1133},[1098,7385,7272],{"class":1598},[1098,7387,1148],{"class":1133},[1098,7389,7390],{"class":1232},"pop",[1098,7392,1236],{"class":1133},[1098,7394,7395],{"class":1100,"line":1489},[1098,7396,1395],{"class":1115},[1098,7398,7399,7401,7404,7406,7408,7410,7412,7414,7417,7419,7421,7424],{"class":1100,"line":1509},[1098,7400,1348],{"class":1111},[1098,7402,7403],{"class":4766}," len",[1098,7405,1255],{"class":1133},[1098,7407,1298],{"class":3697},[1098,7409,1148],{"class":1133},[1098,7411,7272],{"class":1598},[1098,7413,2414],{"class":1133},[1098,7415,7416],{"class":1351}," >=",[1098,7418,3698],{"class":3697},[1098,7420,1148],{"class":1133},[1098,7422,7423],{"class":1598},"num_requests",[1098,7425,1441],{"class":1133},[1098,7427,7428,7430,7432,7434,7437],{"class":1100,"line":1515},[1098,7429,1385],{"class":1111},[1098,7431,3698],{"class":3697},[1098,7433,1148],{"class":1133},[1098,7435,7436],{"class":1232},"throttle_failure",[1098,7438,1236],{"class":1133},[1098,7440,7441],{"class":1100,"line":1521},[1098,7442,1395],{"class":1115},[1098,7444,7445,7447,7449,7451,7454],{"class":1100,"line":1547},[1098,7446,2016],{"class":1111},[1098,7448,3698],{"class":3697},[1098,7450,1148],{"class":1133},[1098,7452,7453],{"class":1232},"throttle_success",[1098,7455,1236],{"class":1133},[1098,7457,7458],{"class":1100,"line":1560},[1098,7459,1220],{"emptyLinePlaceholder":1219},[1098,7461,7462,7464,7467,7469,7472],{"class":1100,"line":1580},[1098,7463,1248],{"class":1247},[1098,7465,7466],{"class":1251}," IPRateThrottle",[1098,7468,1255],{"class":1133},[1098,7470,7471],{"class":1258},"AnonRateThrottle",[1098,7473,1262],{"class":1133},[1098,7475,7476,7478,7481],{"class":1100,"line":1585},[1098,7477,1269],{"class":1268},[1098,7479,7480],{"class":1272},"IP-based rate limiting",[1098,7482,1276],{"class":1268},[1098,7484,7485],{"class":1100,"line":1617},[1098,7486,1282],{"class":1115},[1098,7488,7489,7491,7494,7496,7498,7500,7502,7504,7506],{"class":1100,"line":1634},[1098,7490,1288],{"class":1247},[1098,7492,7493],{"class":1291}," get_cache_key",[1098,7495,1255],{"class":1133},[1098,7497,1298],{"class":1297},[1098,7499,1134],{"class":1133},[1098,7501,1304],{"class":1303},[1098,7503,1134],{"class":1133},[1098,7505,4347],{"class":1303},[1098,7507,1262],{"class":1133},[1098,7509,7510,7512,7514,7516,7518,7520,7522],{"class":1100,"line":1652},[1098,7511,1348],{"class":1111},[1098,7513,1304],{"class":1115},[1098,7515,1148],{"class":1133},[1098,7517,1665],{"class":1598},[1098,7519,1148],{"class":1133},[1098,7521,4377],{"class":1598},[1098,7523,1441],{"class":1133},[1098,7525,7526,7528,7530],{"class":1100,"line":1657},[1098,7527,1385],{"class":1111},[1098,7529,7197],{"class":1388},[1098,7531,7532],{"class":1104},"  # Only throttle anonymous requests\n",[1098,7534,7535],{"class":1100,"line":1675},[1098,7536,1395],{"class":1115},[1098,7538,7539,7541,7543,7545,7548,7551],{"class":1100,"line":1680},[1098,7540,2016],{"class":1111},[1098,7542,3698],{"class":3697},[1098,7544,1148],{"class":1133},[1098,7546,7547],{"class":1598},"cache_format",[1098,7549,7550],{"class":1351}," %",[1098,7552,1851],{"class":1133},[1098,7554,7555,7557,7560,7562,7564,7566,7568,7570],{"class":1100,"line":1695},[1098,7556,1857],{"class":1332},[1098,7558,7559],{"class":1336},"scope",[1098,7561,1333],{"class":1332},[1098,7563,1864],{"class":1133},[1098,7565,3698],{"class":3697},[1098,7567,1148],{"class":1133},[1098,7569,7559],{"class":1598},[1098,7571,1873],{"class":1133},[1098,7573,7574,7576,7579,7581,7583,7585,7587,7590,7592,7594],{"class":1100,"line":1714},[1098,7575,1857],{"class":1332},[1098,7577,7578],{"class":1336},"ident",[1098,7580,1333],{"class":1332},[1098,7582,1864],{"class":1133},[1098,7584,3698],{"class":3697},[1098,7586,1148],{"class":1133},[1098,7588,7589],{"class":1232},"get_ident",[1098,7591,1255],{"class":1133},[1098,7593,2677],{"class":1232},[1098,7595,1342],{"class":1133},[1098,7597,7598],{"class":1100,"line":1728},[1098,7599,2005],{"class":1133},[1098,7601,7602],{"class":1100,"line":1746},[1098,7603,1220],{"emptyLinePlaceholder":1219},[1098,7605,7606,7608,7611,7613,7615],{"class":1100,"line":1760},[1098,7607,1248],{"class":1247},[1098,7609,7610],{"class":1251}," DynamicRateThrottle",[1098,7612,1255],{"class":1133},[1098,7614,7126],{"class":1258},[1098,7616,1262],{"class":1133},[1098,7618,7619,7621,7624],{"class":1100,"line":1778},[1098,7620,1269],{"class":1268},[1098,7622,7623],{"class":1272},"Dynamic rate limiting based on user tier",[1098,7625,1276],{"class":1268},[1098,7627,7628],{"class":1100,"line":1783},[1098,7629,1282],{"class":1115},[1098,7631,7632,7634,7637,7639,7641],{"class":1100,"line":1793},[1098,7633,1288],{"class":1247},[1098,7635,7636],{"class":1291}," get_rate",[1098,7638,1255],{"class":1133},[1098,7640,1298],{"class":1297},[1098,7642,1262],{"class":1133},[1098,7644,7645,7647,7650],{"class":1100,"line":1803},[1098,7646,1835],{"class":1268},[1098,7648,7649],{"class":1272},"Get rate based on user tier",[1098,7651,1276],{"class":1268},[1098,7653,7654,7656,7658,7660,7662,7664,7666,7668,7670,7672,7674,7676,7678,7680,7682,7684,7686,7688,7690,7692],{"class":1100,"line":1808},[1098,7655,1348],{"class":1111},[1098,7657,1352],{"class":1351},[1098,7659,4767],{"class":4766},[1098,7661,1255],{"class":1133},[1098,7663,1298],{"class":3697},[1098,7665,1134],{"class":1133},[1098,7667,1417],{"class":1332},[1098,7669,2677],{"class":1336},[1098,7671,1333],{"class":1332},[1098,7673,2414],{"class":1133},[1098,7675,4364],{"class":1351},[1098,7677,1352],{"class":1351},[1098,7679,3698],{"class":3697},[1098,7681,1148],{"class":1133},[1098,7683,2677],{"class":1598},[1098,7685,1148],{"class":1133},[1098,7687,1665],{"class":1598},[1098,7689,1148],{"class":1133},[1098,7691,4377],{"class":1598},[1098,7693,1441],{"class":1133},[1098,7695,7696,7698,7700,7703],{"class":1100,"line":1818},[1098,7697,1385],{"class":1111},[1098,7699,1417],{"class":1332},[1098,7701,7702],{"class":1336},"100/hour",[1098,7704,1999],{"class":1332},[1098,7706,7707],{"class":1100,"line":1832},[1098,7708,1395],{"class":1115},[1098,7710,7711,7713,7715,7717,7719,7721,7723],{"class":1100,"line":1843},[1098,7712,3303],{"class":1115},[1098,7714,1229],{"class":1133},[1098,7716,3698],{"class":3697},[1098,7718,1148],{"class":1133},[1098,7720,2677],{"class":1598},[1098,7722,1148],{"class":1133},[1098,7724,4801],{"class":1598},[1098,7726,7727],{"class":1100,"line":1854},[1098,7728,1395],{"class":1115},[1098,7730,7731,7733,7735,7737,7739,7741,7743,7745,7747,7749,7751,7754,7756,7758,7760],{"class":1100,"line":1876},[1098,7732,1348],{"class":1111},[1098,7734,1624],{"class":1115},[1098,7736,1148],{"class":1133},[1098,7738,4438],{"class":1598},[1098,7740,1148],{"class":1133},[1098,7742,4723],{"class":1232},[1098,7744,1255],{"class":1133},[1098,7746,4450],{"class":1492},[1098,7748,1229],{"class":1133},[1098,7750,1333],{"class":1332},[1098,7752,7753],{"class":1336},"premium",[1098,7755,1333],{"class":1332},[1098,7757,4738],{"class":1133},[1098,7759,4741],{"class":1232},[1098,7761,4744],{"class":1133},[1098,7763,7764,7766,7768,7771],{"class":1100,"line":1896},[1098,7765,1385],{"class":1111},[1098,7767,1417],{"class":1332},[1098,7769,7770],{"class":1336},"10000/hour",[1098,7772,1999],{"class":1332},[1098,7774,7775,7777,7779,7781,7783,7785,7787,7789,7791,7793,7795,7798,7800,7802,7804],{"class":1100,"line":1916},[1098,7776,4932],{"class":1111},[1098,7778,1624],{"class":1115},[1098,7780,1148],{"class":1133},[1098,7782,4438],{"class":1598},[1098,7784,1148],{"class":1133},[1098,7786,4723],{"class":1232},[1098,7788,1255],{"class":1133},[1098,7790,4450],{"class":1492},[1098,7792,1229],{"class":1133},[1098,7794,1333],{"class":1332},[1098,7796,7797],{"class":1336},"pro",[1098,7799,1333],{"class":1332},[1098,7801,4738],{"class":1133},[1098,7803,4741],{"class":1232},[1098,7805,4744],{"class":1133},[1098,7807,7808,7810,7812,7815],{"class":1100,"line":1961},[1098,7809,1385],{"class":1111},[1098,7811,1417],{"class":1332},[1098,7813,7814],{"class":1336},"5000/hour",[1098,7816,1999],{"class":1332},[1098,7818,7819,7821],{"class":1100,"line":1982},[1098,7820,4989],{"class":1111},[1098,7822,1441],{"class":1133},[1098,7824,7825,7827,7829,7832],{"class":1100,"line":2002},[1098,7826,1385],{"class":1111},[1098,7828,1417],{"class":1332},[1098,7830,7831],{"class":1336},"1000/hour",[1098,7833,1999],{"class":1332},[1098,7835,7836],{"class":1100,"line":2008},[1098,7837,1220],{"emptyLinePlaceholder":1219},[1098,7839,7840],{"class":1100,"line":2013},[1098,7841,4820],{"class":1104},[1098,7843,7844,7846,7848,7850,7852],{"class":1100,"line":2028},[1098,7845,1248],{"class":1247},[1098,7847,4845],{"class":1251},[1098,7849,1255],{"class":1133},[1098,7851,4850],{"class":1258},[1098,7853,1262],{"class":1133},[1098,7855,7856,7859,7861,7863,7866,7868,7870,7872,7874],{"class":1100,"line":2038},[1098,7857,7858],{"class":1115},"    throttle_classes ",[1098,7860,1229],{"class":1133},[1098,7862,4538],{"class":1133},[1098,7864,7865],{"class":1115},"BurstRateThrottle",[1098,7867,1134],{"class":1133},[1098,7869,7466],{"class":1115},[1098,7871,1134],{"class":1133},[1098,7873,7610],{"class":1115},[1098,7875,1427],{"class":1133},[1098,7877,7878,7881,7883,7885,7887],{"class":1100,"line":2052},[1098,7879,7880],{"class":1115},"    throttle_scope ",[1098,7882,1229],{"class":1133},[1098,7884,1417],{"class":1332},[1098,7886,1665],{"class":1336},[1098,7888,1999],{"class":1332},[1035,7890,7892],{"id":7891},"_2-input-validation-and-sanitization","2. Input Validation and Sanitization",[1088,7894,7896],{"className":1090,"code":7895,"language":1092,"meta":1093,"style":1093},"# validation.py\nfrom rest_framework import serializers\nfrom django.core.validators import RegexValidator\nimport bleach\nimport re\n\nclass SecureSerializer(serializers.ModelSerializer):\n    \"\"\"Base serializer with security features\"\"\"\n    \n    def validate(self, data):\n        \"\"\"Apply security validations\"\"\"\n        # Sanitize HTML content\n        for field_name, value in data.items():\n            if isinstance(value, str):\n                data[field_name] = self.sanitize_html(value)\n        \n        # Check for SQL injection patterns\n        self.check_sql_injection(data)\n        \n        # Check for XSS patterns\n        self.check_xss_patterns(data)\n        \n        return data\n    \n    def sanitize_html(self, value):\n        \"\"\"Sanitize HTML content\"\"\"\n        allowed_tags = ['p', 'br', 'strong', 'em', 'ul', 'ol', 'li']\n        allowed_attributes = {}\n        \n        return bleach.clean(\n            value,\n            tags=allowed_tags,\n            attributes=allowed_attributes,\n            strip=True\n        )\n    \n    def check_sql_injection(self, data):\n        \"\"\"Check for SQL injection patterns\"\"\"\n        sql_patterns = [\n            r'(\\b(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\\b)',\n            r'(\\b(UNION|OR|AND)\\b.*\\b(SELECT|INSERT|UPDATE|DELETE)\\b)',\n            r'(--|#|/\\*|\\*/)',\n            r'(\\bEXEC\\b|\\bEXECUTE\\b)',\n        ]\n        \n        for field_name, value in data.items():\n            if isinstance(value, str):\n                for pattern in sql_patterns:\n                    if re.search(pattern, value, re.IGNORECASE):\n                        raise serializers.ValidationError(\n                            f'Potential SQL injection detected in {field_name}'\n                        )\n    \n    def check_xss_patterns(self, data):\n        \"\"\"Check for XSS patterns\"\"\"\n        xss_patterns = [\n            r'\u003Cscript[^>]*>.*?\u003C/script>',\n            r'javascript:',\n            r'on\\w+\\s*=',\n            r'\u003Ciframe[^>]*>.*?\u003C/iframe>',\n        ]\n        \n        for field_name, value in data.items():\n            if isinstance(value, str):\n                for pattern in xss_patterns:\n                    if re.search(pattern, value, re.IGNORECASE):\n                        raise serializers.ValidationError(\n                            f'Potential XSS detected in {field_name}'\n                        )\n\nclass UserSerializer(SecureSerializer):\n    \"\"\"Secure user serializer\"\"\"\n    \n    username = serializers.CharField(\n        max_length=150,\n        validators=[\n            RegexValidator(\n                regex=r'^[a-zA-Z0-9_-]+$',\n                message='Username can only contain letters, numbers, underscores, and hyphens'\n            )\n        ]\n    )\n    \n    email = serializers.EmailField()\n    \n    password = serializers.CharField(\n        write_only=True,\n        min_length=8,\n        validators=[\n            RegexValidator(\n                regex=r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]',\n                message='Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character'\n            )\n        ]\n    )\n    \n    class Meta:\n        model = User\n        fields = ['id', 'username', 'email', 'first_name', 'last_name', 'password']\n        read_only_fields = ['id']\n",[1095,7897,7898,7903,7914,7934,7941,7948,7952,7971,7980,7984,8002,8011,8016,8040,8058,8085,8089,8094,8109,8113,8118,8133,8137,8144,8148,8166,8175,8243,8253,8257,8271,8278,8290,8302,8312,8316,8320,8337,8346,8356,8416,8478,8515,8545,8550,8554,8574,8590,8605,8638,8653,8669,8674,8678,8695,8704,8713,8750,8763,8789,8821,8825,8829,8849,8865,8878,8906,8918,8933,8937,8941,8955,8964,8968,8983,8995,9003,9010,9040,9054,9058,9062,9067,9071,9087,9091,9105,9116,9128,9134,9140,9227,9240,9244,9248,9252,9256,9266,9276,9333],{"__ignoreMap":1093},[1098,7899,7900],{"class":1100,"line":1101},[1098,7901,7902],{"class":1104},"# validation.py\n",[1098,7904,7905,7907,7909,7911],{"class":1100,"line":1108},[1098,7906,1122],{"class":1111},[1098,7908,2596],{"class":1115},[1098,7910,1112],{"class":1111},[1098,7912,7913],{"class":1115}," serializers\n",[1098,7915,7916,7918,7920,7922,7924,7926,7929,7931],{"class":1100,"line":1119},[1098,7917,1122],{"class":1111},[1098,7919,1145],{"class":1115},[1098,7921,1148],{"class":1133},[1098,7923,7094],{"class":1115},[1098,7925,1148],{"class":1133},[1098,7927,7928],{"class":1115},"validators ",[1098,7930,1112],{"class":1111},[1098,7932,7933],{"class":1115}," RegexValidator\n",[1098,7935,7936,7938],{"class":1100,"line":1140},[1098,7937,1112],{"class":1111},[1098,7939,7940],{"class":1115}," bleach\n",[1098,7942,7943,7945],{"class":1100,"line":1159},[1098,7944,1112],{"class":1111},[1098,7946,7947],{"class":1115}," re\n",[1098,7949,7950],{"class":1100,"line":1181},[1098,7951,1220],{"emptyLinePlaceholder":1219},[1098,7953,7954,7956,7959,7961,7964,7966,7969],{"class":1100,"line":1199},[1098,7955,1248],{"class":1247},[1098,7957,7958],{"class":1251}," SecureSerializer",[1098,7960,1255],{"class":1133},[1098,7962,7963],{"class":1258},"serializers",[1098,7965,1148],{"class":1133},[1098,7967,7968],{"class":1258},"ModelSerializer",[1098,7970,1262],{"class":1133},[1098,7972,7973,7975,7978],{"class":1100,"line":1216},[1098,7974,1269],{"class":1268},[1098,7976,7977],{"class":1272},"Base serializer with security features",[1098,7979,1276],{"class":1268},[1098,7981,7982],{"class":1100,"line":1223},[1098,7983,1282],{"class":1115},[1098,7985,7986,7988,7991,7993,7995,7997,8000],{"class":1100,"line":1239},[1098,7987,1288],{"class":1247},[1098,7989,7990],{"class":1291}," validate",[1098,7992,1255],{"class":1133},[1098,7994,1298],{"class":1297},[1098,7996,1134],{"class":1133},[1098,7998,7999],{"class":1303}," data",[1098,8001,1262],{"class":1133},[1098,8003,8004,8006,8009],{"class":1100,"line":1244},[1098,8005,1835],{"class":1268},[1098,8007,8008],{"class":1272},"Apply security validations",[1098,8010,1276],{"class":1268},[1098,8012,8013],{"class":1100,"line":1265},[1098,8014,8015],{"class":1104},"        # Sanitize HTML content\n",[1098,8017,8018,8021,8024,8026,8029,8031,8033,8035,8038],{"class":1100,"line":1279},[1098,8019,8020],{"class":1111},"        for",[1098,8022,8023],{"class":1115}," field_name",[1098,8025,1134],{"class":1133},[1098,8027,8028],{"class":1115}," value ",[1098,8030,5027],{"class":1111},[1098,8032,7999],{"class":1115},[1098,8034,1148],{"class":1133},[1098,8036,8037],{"class":1232},"items",[1098,8039,4744],{"class":1133},[1098,8041,8042,8044,8047,8049,8052,8054,8056],{"class":1100,"line":1285},[1098,8043,1550],{"class":1111},[1098,8045,8046],{"class":4766}," isinstance",[1098,8048,1255],{"class":1133},[1098,8050,8051],{"class":1232},"value",[1098,8053,1134],{"class":1133},[1098,8055,3453],{"class":1814},[1098,8057,1262],{"class":1133},[1098,8059,8060,8063,8065,8068,8070,8072,8074,8076,8079,8081,8083],{"class":1100,"line":1309},[1098,8061,8062],{"class":1115},"                data",[1098,8064,3327],{"class":1133},[1098,8066,8067],{"class":1115},"field_name",[1098,8069,6168],{"class":1133},[1098,8071,5822],{"class":1133},[1098,8073,3698],{"class":3697},[1098,8075,1148],{"class":1133},[1098,8077,8078],{"class":1232},"sanitize_html",[1098,8080,1255],{"class":1133},[1098,8082,8051],{"class":1232},[1098,8084,1342],{"class":1133},[1098,8086,8087],{"class":1100,"line":1345},[1098,8088,1395],{"class":1115},[1098,8090,8091],{"class":1100,"line":1382},[1098,8092,8093],{"class":1104},"        # Check for SQL injection patterns\n",[1098,8095,8096,8098,8100,8103,8105,8107],{"class":1100,"line":1392},[1098,8097,5815],{"class":3697},[1098,8099,1148],{"class":1133},[1098,8101,8102],{"class":1232},"check_sql_injection",[1098,8104,1255],{"class":1133},[1098,8106,2704],{"class":1232},[1098,8108,1342],{"class":1133},[1098,8110,8111],{"class":1100,"line":1398},[1098,8112,1395],{"class":1115},[1098,8114,8115],{"class":1100,"line":1430},[1098,8116,8117],{"class":1104},"        # Check for XSS patterns\n",[1098,8119,8120,8122,8124,8127,8129,8131],{"class":1100,"line":1435},[1098,8121,5815],{"class":3697},[1098,8123,1148],{"class":1133},[1098,8125,8126],{"class":1232},"check_xss_patterns",[1098,8128,1255],{"class":1133},[1098,8130,2704],{"class":1232},[1098,8132,1342],{"class":1133},[1098,8134,8135],{"class":1100,"line":1444},[1098,8136,1395],{"class":1115},[1098,8138,8139,8141],{"class":1100,"line":1463},[1098,8140,2016],{"class":1111},[1098,8142,8143],{"class":1115}," data\n",[1098,8145,8146],{"class":1100,"line":1474},[1098,8147,1282],{"class":1115},[1098,8149,8150,8152,8155,8157,8159,8161,8164],{"class":1100,"line":1489},[1098,8151,1288],{"class":1247},[1098,8153,8154],{"class":1291}," sanitize_html",[1098,8156,1255],{"class":1133},[1098,8158,1298],{"class":1297},[1098,8160,1134],{"class":1133},[1098,8162,8163],{"class":1303}," value",[1098,8165,1262],{"class":1133},[1098,8167,8168,8170,8173],{"class":1100,"line":1509},[1098,8169,1835],{"class":1268},[1098,8171,8172],{"class":1272},"Sanitize HTML content",[1098,8174,1276],{"class":1268},[1098,8176,8177,8180,8182,8184,8186,8188,8190,8192,8194,8197,8199,8201,8203,8205,8207,8209,8211,8214,8216,8218,8220,8223,8225,8227,8229,8231,8233,8235,8237,8239,8241],{"class":1100,"line":1515},[1098,8178,8179],{"class":1115},"        allowed_tags ",[1098,8181,1229],{"class":1133},[1098,8183,4538],{"class":1133},[1098,8185,1333],{"class":1332},[1098,8187,1026],{"class":1336},[1098,8189,1333],{"class":1332},[1098,8191,1134],{"class":1133},[1098,8193,1417],{"class":1332},[1098,8195,8196],{"class":1336},"br",[1098,8198,1333],{"class":1332},[1098,8200,1134],{"class":1133},[1098,8202,1417],{"class":1332},[1098,8204,1046],{"class":1336},[1098,8206,1333],{"class":1332},[1098,8208,1134],{"class":1133},[1098,8210,1417],{"class":1332},[1098,8212,8213],{"class":1336},"em",[1098,8215,1333],{"class":1332},[1098,8217,1134],{"class":1133},[1098,8219,1417],{"class":1332},[1098,8221,8222],{"class":1336},"ul",[1098,8224,1333],{"class":1332},[1098,8226,1134],{"class":1133},[1098,8228,1417],{"class":1332},[1098,8230,1040],{"class":1336},[1098,8232,1333],{"class":1332},[1098,8234,1134],{"class":1133},[1098,8236,1417],{"class":1332},[1098,8238,1043],{"class":1336},[1098,8240,1333],{"class":1332},[1098,8242,1427],{"class":1133},[1098,8244,8245,8248,8250],{"class":1100,"line":1521},[1098,8246,8247],{"class":1115},"        allowed_attributes ",[1098,8249,1229],{"class":1133},[1098,8251,8252],{"class":1133}," {}\n",[1098,8254,8255],{"class":1100,"line":1547},[1098,8256,1395],{"class":1115},[1098,8258,8259,8261,8264,8266,8269],{"class":1100,"line":1560},[1098,8260,2016],{"class":1111},[1098,8262,8263],{"class":1115}," bleach",[1098,8265,1148],{"class":1133},[1098,8267,8268],{"class":1232},"clean",[1098,8270,1460],{"class":1133},[1098,8272,8273,8276],{"class":1100,"line":1580},[1098,8274,8275],{"class":1232},"            value",[1098,8277,1873],{"class":1133},[1098,8279,8280,8283,8285,8288],{"class":1100,"line":1585},[1098,8281,8282],{"class":1492},"            tags",[1098,8284,1229],{"class":1133},[1098,8286,8287],{"class":1232},"allowed_tags",[1098,8289,1873],{"class":1133},[1098,8291,8292,8295,8297,8300],{"class":1100,"line":1617},[1098,8293,8294],{"class":1492},"            attributes",[1098,8296,1229],{"class":1133},[1098,8298,8299],{"class":1232},"allowed_attributes",[1098,8301,1873],{"class":1133},[1098,8303,8304,8307,8309],{"class":1100,"line":1634},[1098,8305,8306],{"class":1492},"            strip",[1098,8308,1229],{"class":1133},[1098,8310,8311],{"class":1388},"True\n",[1098,8313,8314],{"class":1100,"line":1652},[1098,8315,2070],{"class":1133},[1098,8317,8318],{"class":1100,"line":1657},[1098,8319,1282],{"class":1115},[1098,8321,8322,8324,8327,8329,8331,8333,8335],{"class":1100,"line":1675},[1098,8323,1288],{"class":1247},[1098,8325,8326],{"class":1291}," check_sql_injection",[1098,8328,1255],{"class":1133},[1098,8330,1298],{"class":1297},[1098,8332,1134],{"class":1133},[1098,8334,7999],{"class":1303},[1098,8336,1262],{"class":1133},[1098,8338,8339,8341,8344],{"class":1100,"line":1680},[1098,8340,1835],{"class":1268},[1098,8342,8343],{"class":1272},"Check for SQL injection patterns",[1098,8345,1276],{"class":1268},[1098,8347,8348,8351,8353],{"class":1100,"line":1695},[1098,8349,8350],{"class":1115},"        sql_patterns ",[1098,8352,1229],{"class":1133},[1098,8354,8355],{"class":1133}," [\n",[1098,8357,8358,8361,8363,8365,8369,8371,8375,8378,8381,8383,8386,8388,8391,8393,8396,8398,8401,8403,8406,8408,8410,8412,8414],{"class":1100,"line":1714},[1098,8359,8360],{"class":1247},"            r",[1098,8362,1333],{"class":1332},[1098,8364,1255],{"class":1133},[1098,8366,8368],{"class":8367},"sRJPX","\\b",[1098,8370,1255],{"class":1133},[1098,8372,8374],{"class":8373},"s27EL","SELECT",[1098,8376,8377],{"class":1351},"|",[1098,8379,8380],{"class":8373},"INSERT",[1098,8382,8377],{"class":1351},[1098,8384,8385],{"class":8373},"UPDATE",[1098,8387,8377],{"class":1351},[1098,8389,8390],{"class":8373},"DELETE",[1098,8392,8377],{"class":1351},[1098,8394,8395],{"class":8373},"DROP",[1098,8397,8377],{"class":1351},[1098,8399,8400],{"class":8373},"CREATE",[1098,8402,8377],{"class":1351},[1098,8404,8405],{"class":8373},"ALTER",[1098,8407,2414],{"class":1133},[1098,8409,8368],{"class":8367},[1098,8411,2414],{"class":1133},[1098,8413,1333],{"class":1332},[1098,8415,1873],{"class":1133},[1098,8417,8418,8420,8422,8424,8426,8428,8431,8433,8436,8438,8441,8443,8446,8450,8452,8454,8456,8458,8460,8462,8464,8466,8468,8470,8472,8474,8476],{"class":1100,"line":1728},[1098,8419,8360],{"class":1247},[1098,8421,1333],{"class":1332},[1098,8423,1255],{"class":1133},[1098,8425,8368],{"class":8367},[1098,8427,1255],{"class":1133},[1098,8429,8430],{"class":8373},"UNION",[1098,8432,8377],{"class":1351},[1098,8434,8435],{"class":8373},"OR",[1098,8437,8377],{"class":1351},[1098,8439,8440],{"class":8373},"AND",[1098,8442,2414],{"class":1133},[1098,8444,8445],{"class":8367},"\\b.",[1098,8447,8449],{"class":8448},"sGuSu","*",[1098,8451,8368],{"class":8367},[1098,8453,1255],{"class":1133},[1098,8455,8374],{"class":8373},[1098,8457,8377],{"class":1351},[1098,8459,8380],{"class":8373},[1098,8461,8377],{"class":1351},[1098,8463,8385],{"class":8373},[1098,8465,8377],{"class":1351},[1098,8467,8390],{"class":8373},[1098,8469,2414],{"class":1133},[1098,8471,8368],{"class":8367},[1098,8473,2414],{"class":1133},[1098,8475,1333],{"class":1332},[1098,8477,1873],{"class":1133},[1098,8479,8480,8482,8484,8486,8489,8491,8494,8496,8499,8503,8505,8507,8509,8511,8513],{"class":1100,"line":1746},[1098,8481,8360],{"class":1247},[1098,8483,1333],{"class":1332},[1098,8485,1255],{"class":1133},[1098,8487,8488],{"class":8373},"--",[1098,8490,8377],{"class":1351},[1098,8492,8493],{"class":8373},"#",[1098,8495,8377],{"class":1351},[1098,8497,8498],{"class":8373},"/",[1098,8500,8502],{"class":8501},"sk0MF","\\*",[1098,8504,8377],{"class":1351},[1098,8506,8502],{"class":8501},[1098,8508,8498],{"class":8373},[1098,8510,2414],{"class":1133},[1098,8512,1333],{"class":1332},[1098,8514,1873],{"class":1133},[1098,8516,8517,8519,8521,8523,8525,8528,8530,8532,8534,8537,8539,8541,8543],{"class":1100,"line":1760},[1098,8518,8360],{"class":1247},[1098,8520,1333],{"class":1332},[1098,8522,1255],{"class":1133},[1098,8524,8368],{"class":8367},[1098,8526,8527],{"class":8373},"EXEC",[1098,8529,8368],{"class":8367},[1098,8531,8377],{"class":1351},[1098,8533,8368],{"class":8367},[1098,8535,8536],{"class":8373},"EXECUTE",[1098,8538,8368],{"class":8367},[1098,8540,2414],{"class":1133},[1098,8542,1333],{"class":1332},[1098,8544,1873],{"class":1133},[1098,8546,8547],{"class":1100,"line":1778},[1098,8548,8549],{"class":1133},"        ]\n",[1098,8551,8552],{"class":1100,"line":1783},[1098,8553,1395],{"class":1115},[1098,8555,8556,8558,8560,8562,8564,8566,8568,8570,8572],{"class":1100,"line":1793},[1098,8557,8020],{"class":1111},[1098,8559,8023],{"class":1115},[1098,8561,1134],{"class":1133},[1098,8563,8028],{"class":1115},[1098,8565,5027],{"class":1111},[1098,8567,7999],{"class":1115},[1098,8569,1148],{"class":1133},[1098,8571,8037],{"class":1232},[1098,8573,4744],{"class":1133},[1098,8575,8576,8578,8580,8582,8584,8586,8588],{"class":1100,"line":1803},[1098,8577,1550],{"class":1111},[1098,8579,8046],{"class":4766},[1098,8581,1255],{"class":1133},[1098,8583,8051],{"class":1232},[1098,8585,1134],{"class":1133},[1098,8587,3453],{"class":1814},[1098,8589,1262],{"class":1133},[1098,8591,8592,8595,8598,8600,8603],{"class":1100,"line":1808},[1098,8593,8594],{"class":1111},"                for",[1098,8596,8597],{"class":1115}," pattern ",[1098,8599,5027],{"class":1111},[1098,8601,8602],{"class":1115}," sql_patterns",[1098,8604,1441],{"class":1133},[1098,8606,8607,8610,8613,8615,8618,8620,8623,8625,8627,8629,8631,8633,8636],{"class":1100,"line":1818},[1098,8608,8609],{"class":1111},"                    if",[1098,8611,8612],{"class":1115}," re",[1098,8614,1148],{"class":1133},[1098,8616,8617],{"class":1232},"search",[1098,8619,1255],{"class":1133},[1098,8621,8622],{"class":1232},"pattern",[1098,8624,1134],{"class":1133},[1098,8626,8163],{"class":1232},[1098,8628,1134],{"class":1133},[1098,8630,8612],{"class":1232},[1098,8632,1148],{"class":1133},[1098,8634,8635],{"class":1321},"IGNORECASE",[1098,8637,1262],{"class":1133},[1098,8639,8640,8643,8646,8648,8651],{"class":1100,"line":1832},[1098,8641,8642],{"class":1111},"                        raise",[1098,8644,8645],{"class":1115}," serializers",[1098,8647,1148],{"class":1133},[1098,8649,8650],{"class":1232},"ValidationError",[1098,8652,1460],{"class":1133},[1098,8654,8655,8658,8661,8663,8665,8667],{"class":1100,"line":1843},[1098,8656,8657],{"class":1247},"                            f",[1098,8659,8660],{"class":1336},"'Potential SQL injection detected in ",[1098,8662,3874],{"class":3873},[1098,8664,8067],{"class":1232},[1098,8666,3879],{"class":3873},[1098,8668,1999],{"class":1336},[1098,8670,8671],{"class":1100,"line":1854},[1098,8672,8673],{"class":1133},"                        )\n",[1098,8675,8676],{"class":1100,"line":1876},[1098,8677,1282],{"class":1115},[1098,8679,8680,8682,8685,8687,8689,8691,8693],{"class":1100,"line":1896},[1098,8681,1288],{"class":1247},[1098,8683,8684],{"class":1291}," check_xss_patterns",[1098,8686,1255],{"class":1133},[1098,8688,1298],{"class":1297},[1098,8690,1134],{"class":1133},[1098,8692,7999],{"class":1303},[1098,8694,1262],{"class":1133},[1098,8696,8697,8699,8702],{"class":1100,"line":1916},[1098,8698,1835],{"class":1268},[1098,8700,8701],{"class":1272},"Check for XSS patterns",[1098,8703,1276],{"class":1268},[1098,8705,8706,8709,8711],{"class":1100,"line":1961},[1098,8707,8708],{"class":1115},"        xss_patterns ",[1098,8710,1229],{"class":1133},[1098,8712,8355],{"class":1133},[1098,8714,8715,8717,8719,8722,8725,8728,8732,8734,8736,8738,8740,8743,8746,8748],{"class":1100,"line":1982},[1098,8716,8360],{"class":1247},[1098,8718,1333],{"class":1332},[1098,8720,8721],{"class":8373},"\u003Cscript",[1098,8723,3327],{"class":8724},"sETVe",[1098,8726,8727],{"class":1351},"^",[1098,8729,8731],{"class":8730},"sz9Cv",">",[1098,8733,6168],{"class":8724},[1098,8735,8449],{"class":8448},[1098,8737,8731],{"class":8373},[1098,8739,1148],{"class":8367},[1098,8741,8742],{"class":8448},"*?",[1098,8744,8745],{"class":8373},"\u003C/script>",[1098,8747,1333],{"class":1332},[1098,8749,1873],{"class":1133},[1098,8751,8752,8754,8756,8759,8761],{"class":1100,"line":2002},[1098,8753,8360],{"class":1247},[1098,8755,1333],{"class":1332},[1098,8757,8758],{"class":8373},"javascript:",[1098,8760,1333],{"class":1332},[1098,8762,1873],{"class":1133},[1098,8764,8765,8767,8769,8772,8775,8778,8781,8783,8785,8787],{"class":1100,"line":2008},[1098,8766,8360],{"class":1247},[1098,8768,1333],{"class":1332},[1098,8770,8771],{"class":8373},"on",[1098,8773,8774],{"class":8367},"\\w",[1098,8776,8777],{"class":8448},"+",[1098,8779,8780],{"class":8367},"\\s",[1098,8782,8449],{"class":8448},[1098,8784,1229],{"class":8373},[1098,8786,1333],{"class":1332},[1098,8788,1873],{"class":1133},[1098,8790,8791,8793,8795,8798,8800,8802,8804,8806,8808,8810,8812,8814,8817,8819],{"class":1100,"line":2013},[1098,8792,8360],{"class":1247},[1098,8794,1333],{"class":1332},[1098,8796,8797],{"class":8373},"\u003Ciframe",[1098,8799,3327],{"class":8724},[1098,8801,8727],{"class":1351},[1098,8803,8731],{"class":8730},[1098,8805,6168],{"class":8724},[1098,8807,8449],{"class":8448},[1098,8809,8731],{"class":8373},[1098,8811,1148],{"class":8367},[1098,8813,8742],{"class":8448},[1098,8815,8816],{"class":8373},"\u003C/iframe>",[1098,8818,1333],{"class":1332},[1098,8820,1873],{"class":1133},[1098,8822,8823],{"class":1100,"line":2028},[1098,8824,8549],{"class":1133},[1098,8826,8827],{"class":1100,"line":2038},[1098,8828,1395],{"class":1115},[1098,8830,8831,8833,8835,8837,8839,8841,8843,8845,8847],{"class":1100,"line":2052},[1098,8832,8020],{"class":1111},[1098,8834,8023],{"class":1115},[1098,8836,1134],{"class":1133},[1098,8838,8028],{"class":1115},[1098,8840,5027],{"class":1111},[1098,8842,7999],{"class":1115},[1098,8844,1148],{"class":1133},[1098,8846,8037],{"class":1232},[1098,8848,4744],{"class":1133},[1098,8850,8851,8853,8855,8857,8859,8861,8863],{"class":1100,"line":2067},[1098,8852,1550],{"class":1111},[1098,8854,8046],{"class":4766},[1098,8856,1255],{"class":1133},[1098,8858,8051],{"class":1232},[1098,8860,1134],{"class":1133},[1098,8862,3453],{"class":1814},[1098,8864,1262],{"class":1133},[1098,8866,8867,8869,8871,8873,8876],{"class":1100,"line":2073},[1098,8868,8594],{"class":1111},[1098,8870,8597],{"class":1115},[1098,8872,5027],{"class":1111},[1098,8874,8875],{"class":1115}," xss_patterns",[1098,8877,1441],{"class":1133},[1098,8879,8880,8882,8884,8886,8888,8890,8892,8894,8896,8898,8900,8902,8904],{"class":1100,"line":2078},[1098,8881,8609],{"class":1111},[1098,8883,8612],{"class":1115},[1098,8885,1148],{"class":1133},[1098,8887,8617],{"class":1232},[1098,8889,1255],{"class":1133},[1098,8891,8622],{"class":1232},[1098,8893,1134],{"class":1133},[1098,8895,8163],{"class":1232},[1098,8897,1134],{"class":1133},[1098,8899,8612],{"class":1232},[1098,8901,1148],{"class":1133},[1098,8903,8635],{"class":1321},[1098,8905,1262],{"class":1133},[1098,8907,8908,8910,8912,8914,8916],{"class":1100,"line":2085},[1098,8909,8642],{"class":1111},[1098,8911,8645],{"class":1115},[1098,8913,1148],{"class":1133},[1098,8915,8650],{"class":1232},[1098,8917,1460],{"class":1133},[1098,8919,8920,8922,8925,8927,8929,8931],{"class":1100,"line":2099},[1098,8921,8657],{"class":1247},[1098,8923,8924],{"class":1336},"'Potential XSS detected in ",[1098,8926,3874],{"class":3873},[1098,8928,8067],{"class":1232},[1098,8930,3879],{"class":3873},[1098,8932,1999],{"class":1336},[1098,8934,8935],{"class":1100,"line":2109},[1098,8936,8673],{"class":1133},[1098,8938,8939],{"class":1100,"line":2118},[1098,8940,1220],{"emptyLinePlaceholder":1219},[1098,8942,8943,8945,8948,8950,8953],{"class":1100,"line":2137},[1098,8944,1248],{"class":1247},[1098,8946,8947],{"class":1251}," UserSerializer",[1098,8949,1255],{"class":1133},[1098,8951,8952],{"class":1258},"SecureSerializer",[1098,8954,1262],{"class":1133},[1098,8956,8957,8959,8962],{"class":1100,"line":2176},[1098,8958,1269],{"class":1268},[1098,8960,8961],{"class":1272},"Secure user serializer",[1098,8963,1276],{"class":1268},[1098,8965,8966],{"class":1100,"line":2195},[1098,8967,1282],{"class":1115},[1098,8969,8970,8972,8974,8976,8978,8981],{"class":1100,"line":2213},[1098,8971,2695],{"class":1115},[1098,8973,1229],{"class":1133},[1098,8975,8645],{"class":1115},[1098,8977,1148],{"class":1133},[1098,8979,8980],{"class":1232},"CharField",[1098,8982,1460],{"class":1133},[1098,8984,8985,8988,8990,8993],{"class":1100,"line":2218},[1098,8986,8987],{"class":1492},"        max_length",[1098,8989,1229],{"class":1133},[1098,8991,8992],{"class":1423},"150",[1098,8994,1873],{"class":1133},[1098,8996,8997,9000],{"class":1100,"line":2223},[1098,8998,8999],{"class":1492},"        validators",[1098,9001,9002],{"class":1133},"=[\n",[1098,9004,9005,9008],{"class":1100,"line":2236},[1098,9006,9007],{"class":1232},"            RegexValidator",[1098,9009,1460],{"class":1133},[1098,9011,9012,9015,9017,9020,9022,9024,9026,9029,9031,9033,9036,9038],{"class":1100,"line":2245},[1098,9013,9014],{"class":1492},"                regex",[1098,9016,1229],{"class":1133},[1098,9018,9019],{"class":1247},"r",[1098,9021,1333],{"class":1332},[1098,9023,8727],{"class":8367},[1098,9025,3327],{"class":8724},[1098,9027,9028],{"class":8730},"a-zA-Z0-9_-",[1098,9030,6168],{"class":8724},[1098,9032,8777],{"class":8448},[1098,9034,9035],{"class":8367},"$",[1098,9037,1333],{"class":1332},[1098,9039,1873],{"class":1133},[1098,9041,9042,9045,9047,9049,9052],{"class":1100,"line":2258},[1098,9043,9044],{"class":1492},"                message",[1098,9046,1229],{"class":1133},[1098,9048,1333],{"class":1332},[1098,9050,9051],{"class":1336},"Username can only contain letters, numbers, underscores, and hyphens",[1098,9053,1999],{"class":1332},[1098,9055,9056],{"class":1100,"line":2271},[1098,9057,1512],{"class":1133},[1098,9059,9060],{"class":1100,"line":2276},[1098,9061,8549],{"class":1133},[1098,9063,9064],{"class":1100,"line":2281},[1098,9065,9066],{"class":1133},"    )\n",[1098,9068,9069],{"class":1100,"line":2288},[1098,9070,1282],{"class":1115},[1098,9072,9073,9076,9078,9080,9082,9085],{"class":1100,"line":2316},[1098,9074,9075],{"class":1115},"    email ",[1098,9077,1229],{"class":1133},[1098,9079,8645],{"class":1115},[1098,9081,1148],{"class":1133},[1098,9083,9084],{"class":1232},"EmailField",[1098,9086,1236],{"class":1133},[1098,9088,9089],{"class":1100,"line":2326},[1098,9090,1282],{"class":1115},[1098,9092,9093,9095,9097,9099,9101,9103],{"class":1100,"line":2333},[1098,9094,2724],{"class":1115},[1098,9096,1229],{"class":1133},[1098,9098,8645],{"class":1115},[1098,9100,1148],{"class":1133},[1098,9102,8980],{"class":1232},[1098,9104,1460],{"class":1133},[1098,9106,9107,9110,9112,9114],{"class":1100,"line":2348},[1098,9108,9109],{"class":1492},"        write_only",[1098,9111,1229],{"class":1133},[1098,9113,4462],{"class":1388},[1098,9115,1873],{"class":1133},[1098,9117,9118,9121,9123,9126],{"class":1100,"line":2357},[1098,9119,9120],{"class":1492},"        min_length",[1098,9122,1229],{"class":1133},[1098,9124,9125],{"class":1423},"8",[1098,9127,1873],{"class":1133},[1098,9129,9130,9132],{"class":1100,"line":2370},[1098,9131,8999],{"class":1492},[1098,9133,9002],{"class":1133},[1098,9135,9136,9138],{"class":1100,"line":2385},[1098,9137,9007],{"class":1232},[1098,9139,1460],{"class":1133},[1098,9141,9142,9144,9146,9148,9150,9152,9154,9157,9159,9161,9163,9166,9168,9171,9173,9175,9177,9179,9182,9184,9186,9188,9190,9192,9195,9197,9199,9201,9203,9205,9208,9210,9212,9214,9217,9219,9221,9223,9225],{"class":1100,"line":2390},[1098,9143,9014],{"class":1492},[1098,9145,1229],{"class":1133},[1098,9147,9019],{"class":1247},[1098,9149,1333],{"class":1332},[1098,9151,8727],{"class":8367},[1098,9153,1255],{"class":1133},[1098,9155,9156],{"class":1351},"?=",[1098,9158,1148],{"class":8367},[1098,9160,8449],{"class":8448},[1098,9162,3327],{"class":8724},[1098,9164,9165],{"class":8730},"a-z",[1098,9167,6168],{"class":8724},[1098,9169,9170],{"class":1133},")(",[1098,9172,9156],{"class":1351},[1098,9174,1148],{"class":8367},[1098,9176,8449],{"class":8448},[1098,9178,3327],{"class":8724},[1098,9180,9181],{"class":8730},"A-Z",[1098,9183,6168],{"class":8724},[1098,9185,9170],{"class":1133},[1098,9187,9156],{"class":1351},[1098,9189,1148],{"class":8367},[1098,9191,8449],{"class":8448},[1098,9193,9194],{"class":8367},"\\d",[1098,9196,9170],{"class":1133},[1098,9198,9156],{"class":1351},[1098,9200,1148],{"class":8367},[1098,9202,8449],{"class":8448},[1098,9204,3327],{"class":8724},[1098,9206,9207],{"class":8730},"@$!%*?&",[1098,9209,6168],{"class":8724},[1098,9211,2414],{"class":1133},[1098,9213,3327],{"class":8724},[1098,9215,9216],{"class":8730},"A-Za-z",[1098,9218,9194],{"class":8367},[1098,9220,9207],{"class":8730},[1098,9222,6168],{"class":8724},[1098,9224,1333],{"class":1332},[1098,9226,1873],{"class":1133},[1098,9228,9229,9231,9233,9235,9238],{"class":1100,"line":2395},[1098,9230,9044],{"class":1492},[1098,9232,1229],{"class":1133},[1098,9234,1333],{"class":1332},[1098,9236,9237],{"class":1336},"Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character",[1098,9239,1999],{"class":1332},[1098,9241,9242],{"class":1100,"line":2424},[1098,9243,1512],{"class":1133},[1098,9245,9246],{"class":1100,"line":2446},[1098,9247,8549],{"class":1133},[1098,9249,9250],{"class":1100,"line":2451},[1098,9251,9066],{"class":1133},[1098,9253,9254],{"class":1100,"line":2459},[1098,9255,1282],{"class":1115},[1098,9257,9258,9261,9264],{"class":1100,"line":2464},[1098,9259,9260],{"class":1247},"    class",[1098,9262,9263],{"class":1251}," Meta",[1098,9265,1441],{"class":1133},[1098,9267,9268,9271,9273],{"class":1100,"line":2477},[1098,9269,9270],{"class":1115},"        model ",[1098,9272,1229],{"class":1133},[1098,9274,9275],{"class":1115}," User\n",[1098,9277,9278,9281,9283,9285,9287,9289,9291,9293,9295,9297,9299,9301,9303,9305,9307,9309,9311,9313,9315,9317,9319,9321,9323,9325,9327,9329,9331],{"class":1100,"line":2494},[1098,9279,9280],{"class":1115},"        fields ",[1098,9282,1229],{"class":1133},[1098,9284,4538],{"class":1133},[1098,9286,1333],{"class":1332},[1098,9288,1608],{"class":1336},[1098,9290,1333],{"class":1332},[1098,9292,1134],{"class":1133},[1098,9294,1417],{"class":1332},[1098,9296,1881],{"class":1336},[1098,9298,1333],{"class":1332},[1098,9300,1134],{"class":1133},[1098,9302,1417],{"class":1332},[1098,9304,1901],{"class":1336},[1098,9306,1333],{"class":1332},[1098,9308,1134],{"class":1133},[1098,9310,1417],{"class":1332},[1098,9312,4137],{"class":1336},[1098,9314,1333],{"class":1332},[1098,9316,1134],{"class":1133},[1098,9318,1417],{"class":1332},[1098,9320,4170],{"class":1336},[1098,9322,1333],{"class":1332},[1098,9324,1134],{"class":1133},[1098,9326,1417],{"class":1332},[1098,9328,2743],{"class":1336},[1098,9330,1333],{"class":1332},[1098,9332,1427],{"class":1133},[1098,9334,9335,9338,9340,9342,9344,9346,9348],{"class":1100,"line":2507},[1098,9336,9337],{"class":1115},"        read_only_fields ",[1098,9339,1229],{"class":1133},[1098,9341,4538],{"class":1133},[1098,9343,1333],{"class":1332},[1098,9345,1608],{"class":1336},[1098,9347,1333],{"class":1332},[1098,9349,1427],{"class":1133},[1030,9351,1066],{"id":9352},"data-protection",[1035,9354,9356],{"id":9355},"_1-encryption-at-rest","1. Encryption at Rest",[1088,9358,9360],{"className":1090,"code":9359,"language":1092,"meta":1093,"style":1093},"# encryption.py\nfrom cryptography.fernet import Fernet\nfrom django.conf import settings\nfrom django.db import models\nimport base64\n\nclass EncryptedField(models.TextField):\n    \"\"\"Encrypted database field\"\"\"\n    \n    def __init__(self, *args, **kwargs):\n        self.cipher_suite = Fernet(settings.ENCRYPTION_KEY.encode())\n        super().__init__(*args, **kwargs)\n    \n    def from_db_value(self, value, expression, connection):\n        if value is None:\n            return value\n        \n        try:\n            # Decrypt the value\n            decrypted = self.cipher_suite.decrypt(value.encode())\n            return decrypted.decode()\n        except Exception:\n            return value\n    \n    def to_python(self, value):\n        if isinstance(value, str):\n            return value\n        \n        if value is None:\n            return value\n        \n        return str(value)\n    \n    def get_prep_value(self, value):\n        if value is None:\n            return value\n        \n        # Encrypt the value\n        encrypted = self.cipher_suite.encrypt(value.encode())\n        return encrypted.decode()\n\n# Usage in models\nclass UserProfile(models.Model):\n    user = models.OneToOneField(User, on_delete=models.CASCADE)\n    bio = models.TextField()\n    phone_number = EncryptedField()  # Encrypted field\n    ssn = EncryptedField()  # Encrypted field\n    \n    class Meta:\n        db_table = 'user_profiles'\n\n# Encryption utilities\nclass DataEncryption:\n    \"\"\"Data encryption utilities\"\"\"\n    \n    def __init__(self):\n        self.cipher_suite = Fernet(settings.ENCRYPTION_KEY.encode())\n    \n    def encrypt_data(self, data):\n        \"\"\"Encrypt sensitive data\"\"\"\n        if isinstance(data, str):\n            data = data.encode()\n        \n        encrypted = self.cipher_suite.encrypt(data)\n        return base64.b64encode(encrypted).decode()\n    \n    def decrypt_data(self, encrypted_data):\n        \"\"\"Decrypt sensitive data\"\"\"\n        try:\n            decoded = base64.b64decode(encrypted_data.encode())\n            decrypted = self.cipher_suite.decrypt(decoded)\n            return decrypted.decode()\n        except Exception as e:\n            raise ValueError(f\"Decryption failed: {e}\")\n    \n    def encrypt_file(self, file_path, output_path):\n        \"\"\"Encrypt file\"\"\"\n        with open(file_path, 'rb') as file:\n            file_data = file.read()\n        \n        encrypted_data = self.cipher_suite.encrypt(file_data)\n        \n        with open(output_path, 'wb') as file:\n            file.write(encrypted_data)\n    \n    def decrypt_file(self, encrypted_file_path, output_path):\n        \"\"\"Decrypt file\"\"\"\n        with open(encrypted_file_path, 'rb') as file:\n            encrypted_data = file.read()\n        \n        decrypted_data = self.cipher_suite.decrypt(encrypted_data)\n        \n        with open(output_path, 'wb') as file:\n            file.write(decrypted_data)\n",[1095,9361,9362,9367,9384,9398,9414,9421,9425,9444,9453,9457,9483,9512,9537,9541,9568,9581,9588,9592,9598,9603,9631,9644,9653,9659,9663,9680,9696,9702,9706,9718,9724,9728,9740,9744,9761,9773,9779,9783,9788,9816,9829,9833,9838,9856,9891,9906,9920,9933,9937,9945,9959,9963,9968,9977,9986,9990,10002,10028,10032,10049,10058,10074,10089,10093,10115,10138,10142,10160,10169,10175,10200,10223,10235,10247,10271,10275,10298,10307,10339,10355,10359,10383,10387,10415,10431,10435,10457,10466,10493,10508,10512,10535,10539,10565],{"__ignoreMap":1093},[1098,9363,9364],{"class":1100,"line":1101},[1098,9365,9366],{"class":1104},"# encryption.py\n",[1098,9368,9369,9371,9374,9376,9379,9381],{"class":1100,"line":1108},[1098,9370,1122],{"class":1111},[1098,9372,9373],{"class":1115}," cryptography",[1098,9375,1148],{"class":1133},[1098,9377,9378],{"class":1115},"fernet ",[1098,9380,1112],{"class":1111},[1098,9382,9383],{"class":1115}," Fernet\n",[1098,9385,9386,9388,9390,9392,9394,9396],{"class":1100,"line":1119},[1098,9387,1122],{"class":1111},[1098,9389,1145],{"class":1115},[1098,9391,1148],{"class":1133},[1098,9393,1151],{"class":1115},[1098,9395,1112],{"class":1111},[1098,9397,1156],{"class":1115},[1098,9399,9400,9402,9404,9406,9409,9411],{"class":1100,"line":1140},[1098,9401,1122],{"class":1111},[1098,9403,1145],{"class":1115},[1098,9405,1148],{"class":1133},[1098,9407,9408],{"class":1115},"db ",[1098,9410,1112],{"class":1111},[1098,9412,9413],{"class":1115}," models\n",[1098,9415,9416,9418],{"class":1100,"line":1159},[1098,9417,1112],{"class":1111},[1098,9419,9420],{"class":1115}," base64\n",[1098,9422,9423],{"class":1100,"line":1181},[1098,9424,1220],{"emptyLinePlaceholder":1219},[1098,9426,9427,9429,9432,9434,9437,9439,9442],{"class":1100,"line":1199},[1098,9428,1248],{"class":1247},[1098,9430,9431],{"class":1251}," EncryptedField",[1098,9433,1255],{"class":1133},[1098,9435,9436],{"class":1258},"models",[1098,9438,1148],{"class":1133},[1098,9440,9441],{"class":1258},"TextField",[1098,9443,1262],{"class":1133},[1098,9445,9446,9448,9451],{"class":1100,"line":1216},[1098,9447,1269],{"class":1268},[1098,9449,9450],{"class":1272},"Encrypted database field",[1098,9452,1276],{"class":1268},[1098,9454,9455],{"class":1100,"line":1223},[1098,9456,1282],{"class":1115},[1098,9458,9459,9461,9463,9465,9467,9469,9472,9475,9477,9479,9481],{"class":1100,"line":1239},[1098,9460,1288],{"class":1247},[1098,9462,5800],{"class":4766},[1098,9464,1255],{"class":1133},[1098,9466,1298],{"class":1297},[1098,9468,1134],{"class":1133},[1098,9470,9471],{"class":1351}," *",[1098,9473,9474],{"class":1303},"args",[1098,9476,1134],{"class":1133},[1098,9478,5986],{"class":1351},[1098,9480,5989],{"class":1303},[1098,9482,1262],{"class":1133},[1098,9484,9485,9487,9489,9492,9494,9497,9499,9501,9503,9506,9508,9510],{"class":1100,"line":1244},[1098,9486,5815],{"class":3697},[1098,9488,1148],{"class":1133},[1098,9490,9491],{"class":1598},"cipher_suite",[1098,9493,5822],{"class":1133},[1098,9495,9496],{"class":1232}," Fernet",[1098,9498,1255],{"class":1133},[1098,9500,1499],{"class":1232},[1098,9502,1148],{"class":1133},[1098,9504,9505],{"class":1321},"ENCRYPTION_KEY",[1098,9507,1148],{"class":1133},[1098,9509,2023],{"class":1232},[1098,9511,6019],{"class":1133},[1098,9513,9514,9517,9520,9523,9525,9527,9529,9531,9533,9535],{"class":1100,"line":1265},[1098,9515,9516],{"class":1814},"        super",[1098,9518,9519],{"class":1133},"().",[1098,9521,9522],{"class":4766},"__init__",[1098,9524,1255],{"class":1133},[1098,9526,8449],{"class":1351},[1098,9528,9474],{"class":1232},[1098,9530,1134],{"class":1133},[1098,9532,5986],{"class":1351},[1098,9534,5989],{"class":1232},[1098,9536,1342],{"class":1133},[1098,9538,9539],{"class":1100,"line":1279},[1098,9540,1282],{"class":1115},[1098,9542,9543,9545,9548,9550,9552,9554,9556,9558,9561,9563,9566],{"class":1100,"line":1285},[1098,9544,1288],{"class":1247},[1098,9546,9547],{"class":1291}," from_db_value",[1098,9549,1255],{"class":1133},[1098,9551,1298],{"class":1297},[1098,9553,1134],{"class":1133},[1098,9555,8163],{"class":1303},[1098,9557,1134],{"class":1133},[1098,9559,9560],{"class":1303}," expression",[1098,9562,1134],{"class":1133},[1098,9564,9565],{"class":1303}," connection",[1098,9567,1262],{"class":1133},[1098,9569,9570,9572,9574,9577,9579],{"class":1100,"line":1309},[1098,9571,1348],{"class":1111},[1098,9573,8028],{"class":1115},[1098,9575,9576],{"class":1351},"is",[1098,9578,7197],{"class":1388},[1098,9580,1441],{"class":1133},[1098,9582,9583,9585],{"class":1100,"line":1345},[1098,9584,1385],{"class":1111},[1098,9586,9587],{"class":1115}," value\n",[1098,9589,9590],{"class":1100,"line":1382},[1098,9591,1395],{"class":1115},[1098,9593,9594,9596],{"class":1100,"line":1392},[1098,9595,1438],{"class":1111},[1098,9597,1441],{"class":1133},[1098,9599,9600],{"class":1100,"line":1398},[1098,9601,9602],{"class":1104},"            # Decrypt the value\n",[1098,9604,9605,9608,9610,9612,9614,9616,9618,9621,9623,9625,9627,9629],{"class":1100,"line":1430},[1098,9606,9607],{"class":1115},"            decrypted ",[1098,9609,1229],{"class":1133},[1098,9611,3698],{"class":3697},[1098,9613,1148],{"class":1133},[1098,9615,9491],{"class":1598},[1098,9617,1148],{"class":1133},[1098,9619,9620],{"class":1232},"decrypt",[1098,9622,1255],{"class":1133},[1098,9624,8051],{"class":1232},[1098,9626,1148],{"class":1133},[1098,9628,2023],{"class":1232},[1098,9630,6019],{"class":1133},[1098,9632,9633,9635,9638,9640,9642],{"class":1100,"line":1435},[1098,9634,1385],{"class":1111},[1098,9636,9637],{"class":1115}," decrypted",[1098,9639,1148],{"class":1133},[1098,9641,1457],{"class":1232},[1098,9643,1236],{"class":1133},[1098,9645,9646,9648,9651],{"class":1100,"line":1444},[1098,9647,1683],{"class":1111},[1098,9649,9650],{"class":1814}," Exception",[1098,9652,1441],{"class":1133},[1098,9654,9655,9657],{"class":1100,"line":1463},[1098,9656,1385],{"class":1111},[1098,9658,9587],{"class":1115},[1098,9660,9661],{"class":1100,"line":1474},[1098,9662,1282],{"class":1115},[1098,9664,9665,9667,9670,9672,9674,9676,9678],{"class":1100,"line":1489},[1098,9666,1288],{"class":1247},[1098,9668,9669],{"class":1291}," to_python",[1098,9671,1255],{"class":1133},[1098,9673,1298],{"class":1297},[1098,9675,1134],{"class":1133},[1098,9677,8163],{"class":1303},[1098,9679,1262],{"class":1133},[1098,9681,9682,9684,9686,9688,9690,9692,9694],{"class":1100,"line":1509},[1098,9683,1348],{"class":1111},[1098,9685,8046],{"class":4766},[1098,9687,1255],{"class":1133},[1098,9689,8051],{"class":1232},[1098,9691,1134],{"class":1133},[1098,9693,3453],{"class":1814},[1098,9695,1262],{"class":1133},[1098,9697,9698,9700],{"class":1100,"line":1515},[1098,9699,1385],{"class":1111},[1098,9701,9587],{"class":1115},[1098,9703,9704],{"class":1100,"line":1521},[1098,9705,1395],{"class":1115},[1098,9707,9708,9710,9712,9714,9716],{"class":1100,"line":1547},[1098,9709,1348],{"class":1111},[1098,9711,8028],{"class":1115},[1098,9713,9576],{"class":1351},[1098,9715,7197],{"class":1388},[1098,9717,1441],{"class":1133},[1098,9719,9720,9722],{"class":1100,"line":1560},[1098,9721,1385],{"class":1111},[1098,9723,9587],{"class":1115},[1098,9725,9726],{"class":1100,"line":1580},[1098,9727,1395],{"class":1115},[1098,9729,9730,9732,9734,9736,9738],{"class":1100,"line":1585},[1098,9731,2016],{"class":1111},[1098,9733,3453],{"class":1814},[1098,9735,1255],{"class":1133},[1098,9737,8051],{"class":1232},[1098,9739,1342],{"class":1133},[1098,9741,9742],{"class":1100,"line":1617},[1098,9743,1282],{"class":1115},[1098,9745,9746,9748,9751,9753,9755,9757,9759],{"class":1100,"line":1634},[1098,9747,1288],{"class":1247},[1098,9749,9750],{"class":1291}," get_prep_value",[1098,9752,1255],{"class":1133},[1098,9754,1298],{"class":1297},[1098,9756,1134],{"class":1133},[1098,9758,8163],{"class":1303},[1098,9760,1262],{"class":1133},[1098,9762,9763,9765,9767,9769,9771],{"class":1100,"line":1652},[1098,9764,1348],{"class":1111},[1098,9766,8028],{"class":1115},[1098,9768,9576],{"class":1351},[1098,9770,7197],{"class":1388},[1098,9772,1441],{"class":1133},[1098,9774,9775,9777],{"class":1100,"line":1657},[1098,9776,1385],{"class":1111},[1098,9778,9587],{"class":1115},[1098,9780,9781],{"class":1100,"line":1675},[1098,9782,1395],{"class":1115},[1098,9784,9785],{"class":1100,"line":1680},[1098,9786,9787],{"class":1104},"        # Encrypt the value\n",[1098,9789,9790,9793,9795,9797,9799,9801,9803,9806,9808,9810,9812,9814],{"class":1100,"line":1695},[1098,9791,9792],{"class":1115},"        encrypted ",[1098,9794,1229],{"class":1133},[1098,9796,3698],{"class":3697},[1098,9798,1148],{"class":1133},[1098,9800,9491],{"class":1598},[1098,9802,1148],{"class":1133},[1098,9804,9805],{"class":1232},"encrypt",[1098,9807,1255],{"class":1133},[1098,9809,8051],{"class":1232},[1098,9811,1148],{"class":1133},[1098,9813,2023],{"class":1232},[1098,9815,6019],{"class":1133},[1098,9817,9818,9820,9823,9825,9827],{"class":1100,"line":1714},[1098,9819,2016],{"class":1111},[1098,9821,9822],{"class":1115}," encrypted",[1098,9824,1148],{"class":1133},[1098,9826,1457],{"class":1232},[1098,9828,1236],{"class":1133},[1098,9830,9831],{"class":1100,"line":1728},[1098,9832,1220],{"emptyLinePlaceholder":1219},[1098,9834,9835],{"class":1100,"line":1746},[1098,9836,9837],{"class":1104},"# Usage in models\n",[1098,9839,9840,9842,9845,9847,9849,9851,9854],{"class":1100,"line":1760},[1098,9841,1248],{"class":1247},[1098,9843,9844],{"class":1251}," UserProfile",[1098,9846,1255],{"class":1133},[1098,9848,9436],{"class":1258},[1098,9850,1148],{"class":1133},[1098,9852,9853],{"class":1258},"Model",[1098,9855,1262],{"class":1133},[1098,9857,9858,9860,9862,9865,9867,9870,9872,9875,9877,9880,9882,9884,9886,9889],{"class":1100,"line":1778},[1098,9859,2841],{"class":1115},[1098,9861,1229],{"class":1133},[1098,9863,9864],{"class":1115}," models",[1098,9866,1148],{"class":1133},[1098,9868,9869],{"class":1232},"OneToOneField",[1098,9871,1255],{"class":1133},[1098,9873,9874],{"class":1232},"User",[1098,9876,1134],{"class":1133},[1098,9878,9879],{"class":1492}," on_delete",[1098,9881,1229],{"class":1133},[1098,9883,9436],{"class":1232},[1098,9885,1148],{"class":1133},[1098,9887,9888],{"class":1321},"CASCADE",[1098,9890,1342],{"class":1133},[1098,9892,9893,9896,9898,9900,9902,9904],{"class":1100,"line":1783},[1098,9894,9895],{"class":1115},"    bio ",[1098,9897,1229],{"class":1133},[1098,9899,9864],{"class":1115},[1098,9901,1148],{"class":1133},[1098,9903,9441],{"class":1232},[1098,9905,1236],{"class":1133},[1098,9907,9908,9911,9913,9915,9917],{"class":1100,"line":1793},[1098,9909,9910],{"class":1115},"    phone_number ",[1098,9912,1229],{"class":1133},[1098,9914,9431],{"class":1232},[1098,9916,1935],{"class":1133},[1098,9918,9919],{"class":1104},"  # Encrypted field\n",[1098,9921,9922,9925,9927,9929,9931],{"class":1100,"line":1803},[1098,9923,9924],{"class":1115},"    ssn ",[1098,9926,1229],{"class":1133},[1098,9928,9431],{"class":1232},[1098,9930,1935],{"class":1133},[1098,9932,9919],{"class":1104},[1098,9934,9935],{"class":1100,"line":1808},[1098,9936,1282],{"class":1115},[1098,9938,9939,9941,9943],{"class":1100,"line":1818},[1098,9940,9260],{"class":1247},[1098,9942,9263],{"class":1251},[1098,9944,1441],{"class":1133},[1098,9946,9947,9950,9952,9954,9957],{"class":1100,"line":1832},[1098,9948,9949],{"class":1115},"        db_table ",[1098,9951,1229],{"class":1133},[1098,9953,1417],{"class":1332},[1098,9955,9956],{"class":1336},"user_profiles",[1098,9958,1999],{"class":1332},[1098,9960,9961],{"class":1100,"line":1843},[1098,9962,1220],{"emptyLinePlaceholder":1219},[1098,9964,9965],{"class":1100,"line":1854},[1098,9966,9967],{"class":1104},"# Encryption utilities\n",[1098,9969,9970,9972,9975],{"class":1100,"line":1876},[1098,9971,1248],{"class":1247},[1098,9973,9974],{"class":1251}," DataEncryption",[1098,9976,1441],{"class":1133},[1098,9978,9979,9981,9984],{"class":1100,"line":1896},[1098,9980,1269],{"class":1268},[1098,9982,9983],{"class":1272},"Data encryption utilities",[1098,9985,1276],{"class":1268},[1098,9987,9988],{"class":1100,"line":1916},[1098,9989,1282],{"class":1115},[1098,9991,9992,9994,9996,9998,10000],{"class":1100,"line":1961},[1098,9993,1288],{"class":1247},[1098,9995,5800],{"class":4766},[1098,9997,1255],{"class":1133},[1098,9999,1298],{"class":1297},[1098,10001,1262],{"class":1133},[1098,10003,10004,10006,10008,10010,10012,10014,10016,10018,10020,10022,10024,10026],{"class":1100,"line":1982},[1098,10005,5815],{"class":3697},[1098,10007,1148],{"class":1133},[1098,10009,9491],{"class":1598},[1098,10011,5822],{"class":1133},[1098,10013,9496],{"class":1232},[1098,10015,1255],{"class":1133},[1098,10017,1499],{"class":1232},[1098,10019,1148],{"class":1133},[1098,10021,9505],{"class":1321},[1098,10023,1148],{"class":1133},[1098,10025,2023],{"class":1232},[1098,10027,6019],{"class":1133},[1098,10029,10030],{"class":1100,"line":2002},[1098,10031,1282],{"class":1115},[1098,10033,10034,10036,10039,10041,10043,10045,10047],{"class":1100,"line":2008},[1098,10035,1288],{"class":1247},[1098,10037,10038],{"class":1291}," encrypt_data",[1098,10040,1255],{"class":1133},[1098,10042,1298],{"class":1297},[1098,10044,1134],{"class":1133},[1098,10046,7999],{"class":1303},[1098,10048,1262],{"class":1133},[1098,10050,10051,10053,10056],{"class":1100,"line":2013},[1098,10052,1835],{"class":1268},[1098,10054,10055],{"class":1272},"Encrypt sensitive data",[1098,10057,1276],{"class":1268},[1098,10059,10060,10062,10064,10066,10068,10070,10072],{"class":1100,"line":2028},[1098,10061,1348],{"class":1111},[1098,10063,8046],{"class":4766},[1098,10065,1255],{"class":1133},[1098,10067,2704],{"class":1232},[1098,10069,1134],{"class":1133},[1098,10071,3453],{"class":1814},[1098,10073,1262],{"class":1133},[1098,10075,10076,10079,10081,10083,10085,10087],{"class":1100,"line":2038},[1098,10077,10078],{"class":1115},"            data ",[1098,10080,1229],{"class":1133},[1098,10082,7999],{"class":1115},[1098,10084,1148],{"class":1133},[1098,10086,2023],{"class":1232},[1098,10088,1236],{"class":1133},[1098,10090,10091],{"class":1100,"line":2052},[1098,10092,1395],{"class":1115},[1098,10094,10095,10097,10099,10101,10103,10105,10107,10109,10111,10113],{"class":1100,"line":2067},[1098,10096,9792],{"class":1115},[1098,10098,1229],{"class":1133},[1098,10100,3698],{"class":3697},[1098,10102,1148],{"class":1133},[1098,10104,9491],{"class":1598},[1098,10106,1148],{"class":1133},[1098,10108,9805],{"class":1232},[1098,10110,1255],{"class":1133},[1098,10112,2704],{"class":1232},[1098,10114,1342],{"class":1133},[1098,10116,10117,10119,10122,10124,10127,10129,10132,10134,10136],{"class":1100,"line":2073},[1098,10118,2016],{"class":1111},[1098,10120,10121],{"class":1115}," base64",[1098,10123,1148],{"class":1133},[1098,10125,10126],{"class":1232},"b64encode",[1098,10128,1255],{"class":1133},[1098,10130,10131],{"class":1232},"encrypted",[1098,10133,4738],{"class":1133},[1098,10135,1457],{"class":1232},[1098,10137,1236],{"class":1133},[1098,10139,10140],{"class":1100,"line":2078},[1098,10141,1282],{"class":1115},[1098,10143,10144,10146,10149,10151,10153,10155,10158],{"class":1100,"line":2085},[1098,10145,1288],{"class":1247},[1098,10147,10148],{"class":1291}," decrypt_data",[1098,10150,1255],{"class":1133},[1098,10152,1298],{"class":1297},[1098,10154,1134],{"class":1133},[1098,10156,10157],{"class":1303}," encrypted_data",[1098,10159,1262],{"class":1133},[1098,10161,10162,10164,10167],{"class":1100,"line":2099},[1098,10163,1835],{"class":1268},[1098,10165,10166],{"class":1272},"Decrypt sensitive data",[1098,10168,1276],{"class":1268},[1098,10170,10171,10173],{"class":1100,"line":2109},[1098,10172,1438],{"class":1111},[1098,10174,1441],{"class":1133},[1098,10176,10177,10180,10182,10184,10186,10189,10191,10194,10196,10198],{"class":1100,"line":2118},[1098,10178,10179],{"class":1115},"            decoded ",[1098,10181,1229],{"class":1133},[1098,10183,10121],{"class":1115},[1098,10185,1148],{"class":1133},[1098,10187,10188],{"class":1232},"b64decode",[1098,10190,1255],{"class":1133},[1098,10192,10193],{"class":1232},"encrypted_data",[1098,10195,1148],{"class":1133},[1098,10197,2023],{"class":1232},[1098,10199,6019],{"class":1133},[1098,10201,10202,10204,10206,10208,10210,10212,10214,10216,10218,10221],{"class":1100,"line":2137},[1098,10203,9607],{"class":1115},[1098,10205,1229],{"class":1133},[1098,10207,3698],{"class":3697},[1098,10209,1148],{"class":1133},[1098,10211,9491],{"class":1598},[1098,10213,1148],{"class":1133},[1098,10215,9620],{"class":1232},[1098,10217,1255],{"class":1133},[1098,10219,10220],{"class":1232},"decoded",[1098,10222,1342],{"class":1133},[1098,10224,10225,10227,10229,10231,10233],{"class":1100,"line":2176},[1098,10226,1385],{"class":1111},[1098,10228,9637],{"class":1115},[1098,10230,1148],{"class":1133},[1098,10232,1457],{"class":1232},[1098,10234,1236],{"class":1133},[1098,10236,10237,10239,10241,10243,10245],{"class":1100,"line":2195},[1098,10238,1683],{"class":1111},[1098,10240,9650],{"class":1814},[1098,10242,3423],{"class":1111},[1098,10244,3426],{"class":1115},[1098,10246,1441],{"class":1133},[1098,10248,10249,10251,10253,10255,10258,10261,10263,10265,10267,10269],{"class":1100,"line":2213},[1098,10250,1698],{"class":1111},[1098,10252,5421],{"class":1814},[1098,10254,1255],{"class":1133},[1098,10256,10257],{"class":1247},"f",[1098,10259,10260],{"class":1336},"\"Decryption failed: ",[1098,10262,3874],{"class":3873},[1098,10264,3458],{"class":1232},[1098,10266,3879],{"class":3873},[1098,10268,5680],{"class":1336},[1098,10270,1342],{"class":1133},[1098,10272,10273],{"class":1100,"line":2218},[1098,10274,1282],{"class":1115},[1098,10276,10277,10279,10282,10284,10286,10288,10291,10293,10296],{"class":1100,"line":2223},[1098,10278,1288],{"class":1247},[1098,10280,10281],{"class":1291}," encrypt_file",[1098,10283,1255],{"class":1133},[1098,10285,1298],{"class":1297},[1098,10287,1134],{"class":1133},[1098,10289,10290],{"class":1303}," file_path",[1098,10292,1134],{"class":1133},[1098,10294,10295],{"class":1303}," output_path",[1098,10297,1262],{"class":1133},[1098,10299,10300,10302,10305],{"class":1100,"line":2236},[1098,10301,1835],{"class":1268},[1098,10303,10304],{"class":1272},"Encrypt file",[1098,10306,1276],{"class":1268},[1098,10308,10309,10312,10315,10317,10320,10322,10324,10327,10329,10331,10333,10337],{"class":1100,"line":2245},[1098,10310,10311],{"class":1111},"        with",[1098,10313,10314],{"class":4766}," open",[1098,10316,1255],{"class":1133},[1098,10318,10319],{"class":1232},"file_path",[1098,10321,1134],{"class":1133},[1098,10323,1417],{"class":1332},[1098,10325,10326],{"class":1336},"rb",[1098,10328,1333],{"class":1332},[1098,10330,2414],{"class":1133},[1098,10332,3423],{"class":1111},[1098,10334,10336],{"class":10335},"sSC40"," file",[1098,10338,1441],{"class":1133},[1098,10340,10341,10344,10346,10348,10350,10353],{"class":1100,"line":2258},[1098,10342,10343],{"class":1115},"            file_data ",[1098,10345,1229],{"class":1133},[1098,10347,10336],{"class":10335},[1098,10349,1148],{"class":1133},[1098,10351,10352],{"class":1232},"read",[1098,10354,1236],{"class":1133},[1098,10356,10357],{"class":1100,"line":2271},[1098,10358,1395],{"class":1115},[1098,10360,10361,10364,10366,10368,10370,10372,10374,10376,10378,10381],{"class":1100,"line":2276},[1098,10362,10363],{"class":1115},"        encrypted_data ",[1098,10365,1229],{"class":1133},[1098,10367,3698],{"class":3697},[1098,10369,1148],{"class":1133},[1098,10371,9491],{"class":1598},[1098,10373,1148],{"class":1133},[1098,10375,9805],{"class":1232},[1098,10377,1255],{"class":1133},[1098,10379,10380],{"class":1232},"file_data",[1098,10382,1342],{"class":1133},[1098,10384,10385],{"class":1100,"line":2281},[1098,10386,1395],{"class":1115},[1098,10388,10389,10391,10393,10395,10398,10400,10402,10405,10407,10409,10411,10413],{"class":1100,"line":2288},[1098,10390,10311],{"class":1111},[1098,10392,10314],{"class":4766},[1098,10394,1255],{"class":1133},[1098,10396,10397],{"class":1232},"output_path",[1098,10399,1134],{"class":1133},[1098,10401,1417],{"class":1332},[1098,10403,10404],{"class":1336},"wb",[1098,10406,1333],{"class":1332},[1098,10408,2414],{"class":1133},[1098,10410,3423],{"class":1111},[1098,10412,10336],{"class":10335},[1098,10414,1441],{"class":1133},[1098,10416,10417,10420,10422,10425,10427,10429],{"class":1100,"line":2316},[1098,10418,10419],{"class":10335},"            file",[1098,10421,1148],{"class":1133},[1098,10423,10424],{"class":1232},"write",[1098,10426,1255],{"class":1133},[1098,10428,10193],{"class":1232},[1098,10430,1342],{"class":1133},[1098,10432,10433],{"class":1100,"line":2326},[1098,10434,1282],{"class":1115},[1098,10436,10437,10439,10442,10444,10446,10448,10451,10453,10455],{"class":1100,"line":2333},[1098,10438,1288],{"class":1247},[1098,10440,10441],{"class":1291}," decrypt_file",[1098,10443,1255],{"class":1133},[1098,10445,1298],{"class":1297},[1098,10447,1134],{"class":1133},[1098,10449,10450],{"class":1303}," encrypted_file_path",[1098,10452,1134],{"class":1133},[1098,10454,10295],{"class":1303},[1098,10456,1262],{"class":1133},[1098,10458,10459,10461,10464],{"class":1100,"line":2348},[1098,10460,1835],{"class":1268},[1098,10462,10463],{"class":1272},"Decrypt file",[1098,10465,1276],{"class":1268},[1098,10467,10468,10470,10472,10474,10477,10479,10481,10483,10485,10487,10489,10491],{"class":1100,"line":2357},[1098,10469,10311],{"class":1111},[1098,10471,10314],{"class":4766},[1098,10473,1255],{"class":1133},[1098,10475,10476],{"class":1232},"encrypted_file_path",[1098,10478,1134],{"class":1133},[1098,10480,1417],{"class":1332},[1098,10482,10326],{"class":1336},[1098,10484,1333],{"class":1332},[1098,10486,2414],{"class":1133},[1098,10488,3423],{"class":1111},[1098,10490,10336],{"class":10335},[1098,10492,1441],{"class":1133},[1098,10494,10495,10498,10500,10502,10504,10506],{"class":1100,"line":2370},[1098,10496,10497],{"class":1115},"            encrypted_data ",[1098,10499,1229],{"class":1133},[1098,10501,10336],{"class":10335},[1098,10503,1148],{"class":1133},[1098,10505,10352],{"class":1232},[1098,10507,1236],{"class":1133},[1098,10509,10510],{"class":1100,"line":2385},[1098,10511,1395],{"class":1115},[1098,10513,10514,10517,10519,10521,10523,10525,10527,10529,10531,10533],{"class":1100,"line":2390},[1098,10515,10516],{"class":1115},"        decrypted_data ",[1098,10518,1229],{"class":1133},[1098,10520,3698],{"class":3697},[1098,10522,1148],{"class":1133},[1098,10524,9491],{"class":1598},[1098,10526,1148],{"class":1133},[1098,10528,9620],{"class":1232},[1098,10530,1255],{"class":1133},[1098,10532,10193],{"class":1232},[1098,10534,1342],{"class":1133},[1098,10536,10537],{"class":1100,"line":2395},[1098,10538,1395],{"class":1115},[1098,10540,10541,10543,10545,10547,10549,10551,10553,10555,10557,10559,10561,10563],{"class":1100,"line":2424},[1098,10542,10311],{"class":1111},[1098,10544,10314],{"class":4766},[1098,10546,1255],{"class":1133},[1098,10548,10397],{"class":1232},[1098,10550,1134],{"class":1133},[1098,10552,1417],{"class":1332},[1098,10554,10404],{"class":1336},[1098,10556,1333],{"class":1332},[1098,10558,2414],{"class":1133},[1098,10560,3423],{"class":1111},[1098,10562,10336],{"class":10335},[1098,10564,1441],{"class":1133},[1098,10566,10567,10569,10571,10573,10575,10578],{"class":1100,"line":2446},[1098,10568,10419],{"class":10335},[1098,10570,1148],{"class":1133},[1098,10572,10424],{"class":1232},[1098,10574,1255],{"class":1133},[1098,10576,10577],{"class":1232},"decrypted_data",[1098,10579,1342],{"class":1133},[1035,10581,10583],{"id":10582},"_2-secrets-management","2. Secrets Management",[1088,10585,10587],{"className":1090,"code":10586,"language":1092,"meta":1093,"style":1093},"# secrets_manager.py\nimport boto3\nimport json\nfrom django.conf import settings\nfrom django.core.cache import cache\n\nclass SecretsManager:\n    \"\"\"AWS Secrets Manager integration\"\"\"\n    \n    def __init__(self):\n        self.client = boto3.client(\n            'secretsmanager',\n            region_name=settings.AWS_REGION\n        )\n    \n    def get_secret(self, secret_name, cache_timeout=300):\n        \"\"\"Get secret with caching\"\"\"\n        cache_key = f\"secret:{secret_name}\"\n        secret_value = cache.get(cache_key)\n        \n        if secret_value is None:\n            try:\n                response = self.client.get_secret_value(SecretId=secret_name)\n                secret_value = json.loads(response['SecretString'])\n                cache.set(cache_key, secret_value, timeout=cache_timeout)\n            except Exception as e:\n                raise ValueError(f\"Failed to retrieve secret {secret_name}: {e}\")\n        \n        return secret_value\n    \n    def update_secret(self, secret_name, secret_value):\n        \"\"\"Update secret\"\"\"\n        try:\n            self.client.update_secret(\n                SecretId=secret_name,\n                SecretString=json.dumps(secret_value)\n            )\n            \n            # Invalidate cache\n            cache_key = f\"secret:{secret_name}\"\n            cache.delete(cache_key)\n            \n        except Exception as e:\n            raise ValueError(f\"Failed to update secret {secret_name}: {e}\")\n\n# Kubernetes secrets integration\nclass KubernetesSecretsManager:\n    \"\"\"Kubernetes secrets integration\"\"\"\n    \n    def __init__(self):\n        from kubernetes import client, config\n        \n        try:\n            config.load_incluster_config()\n        except:\n            config.load_kube_config()\n        \n        self.v1 = client.CoreV1Api()\n    \n    def get_secret(self, secret_name, namespace='default'):\n        \"\"\"Get Kubernetes secret\"\"\"\n        try:\n            secret = self.v1.read_namespaced_secret(\n                name=secret_name,\n                namespace=namespace\n            )\n            \n            # Decode base64 encoded values\n            decoded_data = {}\n            for key, value in secret.data.items():\n                decoded_data[key] = base64.b64decode(value).decode()\n            \n            return decoded_data\n            \n        except Exception as e:\n            raise ValueError(f\"Failed to retrieve secret {secret_name}: {e}\")\n\n# Environment-based secrets\nclass EnvironmentSecretsManager:\n    \"\"\"Environment variable based secrets\"\"\"\n    \n    @staticmethod\n    def get_secret(secret_name):\n        \"\"\"Get secret from environment variables\"\"\"\n        import os\n        \n        secret_value = os.getenv(secret_name)\n        if secret_value is None:\n            raise ValueError(f\"Secret {secret_name} not found in environment\")\n        \n        try:\n            # Try to parse as JSON\n            return json.loads(secret_value)\n        except json.JSONDecodeError:\n            # Return as string if not JSON\n            return secret_value\n",[1095,10588,10589,10594,10601,10608,10622,10640,10644,10653,10662,10666,10678,10698,10709,10723,10727,10731,10759,10768,10789,10810,10814,10827,10834,10863,10894,10925,10938,10970,10974,10981,10985,11006,11015,11021,11036,11047,11068,11072,11076,11081,11100,11116,11120,11132,11163,11167,11172,11181,11190,11194,11206,11224,11228,11234,11246,11252,11263,11267,11287,11291,11321,11330,11336,11356,11367,11377,11381,11385,11390,11399,11426,11455,11459,11466,11470,11482,11512,11516,11521,11530,11539,11543,11549,11561,11570,11578,11582,11602,11614,11638,11642,11648,11653,11669,11682,11687],{"__ignoreMap":1093},[1098,10590,10591],{"class":1100,"line":1101},[1098,10592,10593],{"class":1104},"# secrets_manager.py\n",[1098,10595,10596,10598],{"class":1100,"line":1108},[1098,10597,1112],{"class":1111},[1098,10599,10600],{"class":1115}," boto3\n",[1098,10602,10603,10605],{"class":1100,"line":1119},[1098,10604,1112],{"class":1111},[1098,10606,10607],{"class":1115}," json\n",[1098,10609,10610,10612,10614,10616,10618,10620],{"class":1100,"line":1140},[1098,10611,1122],{"class":1111},[1098,10613,1145],{"class":1115},[1098,10615,1148],{"class":1133},[1098,10617,1151],{"class":1115},[1098,10619,1112],{"class":1111},[1098,10621,1156],{"class":1115},[1098,10623,10624,10626,10628,10630,10632,10634,10636,10638],{"class":1100,"line":1159},[1098,10625,1122],{"class":1111},[1098,10627,1145],{"class":1115},[1098,10629,1148],{"class":1133},[1098,10631,7094],{"class":1115},[1098,10633,1148],{"class":1133},[1098,10635,7099],{"class":1115},[1098,10637,1112],{"class":1111},[1098,10639,7104],{"class":1115},[1098,10641,10642],{"class":1100,"line":1181},[1098,10643,1220],{"emptyLinePlaceholder":1219},[1098,10645,10646,10648,10651],{"class":1100,"line":1199},[1098,10647,1248],{"class":1247},[1098,10649,10650],{"class":1251}," SecretsManager",[1098,10652,1441],{"class":1133},[1098,10654,10655,10657,10660],{"class":1100,"line":1216},[1098,10656,1269],{"class":1268},[1098,10658,10659],{"class":1272},"AWS Secrets Manager integration",[1098,10661,1276],{"class":1268},[1098,10663,10664],{"class":1100,"line":1223},[1098,10665,1282],{"class":1115},[1098,10667,10668,10670,10672,10674,10676],{"class":1100,"line":1239},[1098,10669,1288],{"class":1247},[1098,10671,5800],{"class":4766},[1098,10673,1255],{"class":1133},[1098,10675,1298],{"class":1297},[1098,10677,1262],{"class":1133},[1098,10679,10680,10682,10684,10687,10689,10692,10694,10696],{"class":1100,"line":1244},[1098,10681,5815],{"class":3697},[1098,10683,1148],{"class":1133},[1098,10685,10686],{"class":1598},"client",[1098,10688,5822],{"class":1133},[1098,10690,10691],{"class":1115}," boto3",[1098,10693,1148],{"class":1133},[1098,10695,10686],{"class":1232},[1098,10697,1460],{"class":1133},[1098,10699,10700,10702,10705,10707],{"class":1100,"line":1265},[1098,10701,1857],{"class":1332},[1098,10703,10704],{"class":1336},"secretsmanager",[1098,10706,1333],{"class":1332},[1098,10708,1873],{"class":1133},[1098,10710,10711,10714,10716,10718,10720],{"class":1100,"line":1279},[1098,10712,10713],{"class":1492},"            region_name",[1098,10715,1229],{"class":1133},[1098,10717,1499],{"class":1232},[1098,10719,1148],{"class":1133},[1098,10721,10722],{"class":1321},"AWS_REGION\n",[1098,10724,10725],{"class":1100,"line":1285},[1098,10726,2070],{"class":1133},[1098,10728,10729],{"class":1100,"line":1309},[1098,10730,1282],{"class":1115},[1098,10732,10733,10735,10738,10740,10742,10744,10747,10749,10752,10754,10757],{"class":1100,"line":1345},[1098,10734,1288],{"class":1247},[1098,10736,10737],{"class":1291}," get_secret",[1098,10739,1255],{"class":1133},[1098,10741,1298],{"class":1297},[1098,10743,1134],{"class":1133},[1098,10745,10746],{"class":1303}," secret_name",[1098,10748,1134],{"class":1133},[1098,10750,10751],{"class":1303}," cache_timeout",[1098,10753,1229],{"class":1351},[1098,10755,10756],{"class":1423},"300",[1098,10758,1262],{"class":1133},[1098,10760,10761,10763,10766],{"class":1100,"line":1382},[1098,10762,1835],{"class":1268},[1098,10764,10765],{"class":1272},"Get secret with caching",[1098,10767,1276],{"class":1268},[1098,10769,10770,10773,10775,10777,10780,10782,10785,10787],{"class":1100,"line":1392},[1098,10771,10772],{"class":1115},"        cache_key ",[1098,10774,1229],{"class":1133},[1098,10776,3867],{"class":1247},[1098,10778,10779],{"class":1336},"\"secret:",[1098,10781,3874],{"class":3873},[1098,10783,10784],{"class":1115},"secret_name",[1098,10786,3879],{"class":3873},[1098,10788,5705],{"class":1336},[1098,10790,10791,10794,10796,10799,10801,10803,10805,10808],{"class":1100,"line":1398},[1098,10792,10793],{"class":1115},"        secret_value ",[1098,10795,1229],{"class":1133},[1098,10797,10798],{"class":1115}," cache",[1098,10800,1148],{"class":1133},[1098,10802,1327],{"class":1232},[1098,10804,1255],{"class":1133},[1098,10806,10807],{"class":1232},"cache_key",[1098,10809,1342],{"class":1133},[1098,10811,10812],{"class":1100,"line":1430},[1098,10813,1395],{"class":1115},[1098,10815,10816,10818,10821,10823,10825],{"class":1100,"line":1435},[1098,10817,1348],{"class":1111},[1098,10819,10820],{"class":1115}," secret_value ",[1098,10822,9576],{"class":1351},[1098,10824,7197],{"class":1388},[1098,10826,1441],{"class":1133},[1098,10828,10829,10832],{"class":1100,"line":1444},[1098,10830,10831],{"class":1111},"            try",[1098,10833,1441],{"class":1133},[1098,10835,10836,10839,10841,10843,10845,10847,10849,10852,10854,10857,10859,10861],{"class":1100,"line":1463},[1098,10837,10838],{"class":1115},"                response ",[1098,10840,1229],{"class":1133},[1098,10842,3698],{"class":3697},[1098,10844,1148],{"class":1133},[1098,10846,10686],{"class":1598},[1098,10848,1148],{"class":1133},[1098,10850,10851],{"class":1232},"get_secret_value",[1098,10853,1255],{"class":1133},[1098,10855,10856],{"class":1492},"SecretId",[1098,10858,1229],{"class":1133},[1098,10860,10784],{"class":1232},[1098,10862,1342],{"class":1133},[1098,10864,10865,10868,10870,10873,10875,10878,10880,10883,10885,10887,10890,10892],{"class":1100,"line":1474},[1098,10866,10867],{"class":1115},"                secret_value ",[1098,10869,1229],{"class":1133},[1098,10871,10872],{"class":1115}," json",[1098,10874,1148],{"class":1133},[1098,10876,10877],{"class":1232},"loads",[1098,10879,1255],{"class":1133},[1098,10881,10882],{"class":1232},"response",[1098,10884,3327],{"class":1133},[1098,10886,1333],{"class":1332},[1098,10888,10889],{"class":1336},"SecretString",[1098,10891,1333],{"class":1332},[1098,10893,2648],{"class":1133},[1098,10895,10896,10899,10901,10904,10906,10908,10910,10913,10915,10918,10920,10923],{"class":1100,"line":1489},[1098,10897,10898],{"class":1115},"                cache",[1098,10900,1148],{"class":1133},[1098,10902,10903],{"class":1232},"set",[1098,10905,1255],{"class":1133},[1098,10907,10807],{"class":1232},[1098,10909,1134],{"class":1133},[1098,10911,10912],{"class":1232}," secret_value",[1098,10914,1134],{"class":1133},[1098,10916,10917],{"class":1492}," timeout",[1098,10919,1229],{"class":1133},[1098,10921,10922],{"class":1232},"cache_timeout",[1098,10924,1342],{"class":1133},[1098,10926,10927,10930,10932,10934,10936],{"class":1100,"line":1509},[1098,10928,10929],{"class":1111},"            except",[1098,10931,9650],{"class":1814},[1098,10933,3423],{"class":1111},[1098,10935,3426],{"class":1115},[1098,10937,1441],{"class":1133},[1098,10939,10940,10942,10944,10946,10948,10951,10953,10955,10957,10960,10962,10964,10966,10968],{"class":1100,"line":1515},[1098,10941,1563],{"class":1111},[1098,10943,5421],{"class":1814},[1098,10945,1255],{"class":1133},[1098,10947,10257],{"class":1247},[1098,10949,10950],{"class":1336},"\"Failed to retrieve secret ",[1098,10952,3874],{"class":3873},[1098,10954,10784],{"class":1232},[1098,10956,3879],{"class":3873},[1098,10958,10959],{"class":1336},": ",[1098,10961,3874],{"class":3873},[1098,10963,3458],{"class":1232},[1098,10965,3879],{"class":3873},[1098,10967,5680],{"class":1336},[1098,10969,1342],{"class":1133},[1098,10971,10972],{"class":1100,"line":1521},[1098,10973,1395],{"class":1115},[1098,10975,10976,10978],{"class":1100,"line":1547},[1098,10977,2016],{"class":1111},[1098,10979,10980],{"class":1115}," secret_value\n",[1098,10982,10983],{"class":1100,"line":1560},[1098,10984,1282],{"class":1115},[1098,10986,10987,10989,10992,10994,10996,10998,11000,11002,11004],{"class":1100,"line":1580},[1098,10988,1288],{"class":1247},[1098,10990,10991],{"class":1291}," update_secret",[1098,10993,1255],{"class":1133},[1098,10995,1298],{"class":1297},[1098,10997,1134],{"class":1133},[1098,10999,10746],{"class":1303},[1098,11001,1134],{"class":1133},[1098,11003,10912],{"class":1303},[1098,11005,1262],{"class":1133},[1098,11007,11008,11010,11013],{"class":1100,"line":1585},[1098,11009,1835],{"class":1268},[1098,11011,11012],{"class":1272},"Update secret",[1098,11014,1276],{"class":1268},[1098,11016,11017,11019],{"class":1100,"line":1617},[1098,11018,1438],{"class":1111},[1098,11020,1441],{"class":1133},[1098,11022,11023,11025,11027,11029,11031,11034],{"class":1100,"line":1634},[1098,11024,7381],{"class":3697},[1098,11026,1148],{"class":1133},[1098,11028,10686],{"class":1598},[1098,11030,1148],{"class":1133},[1098,11032,11033],{"class":1232},"update_secret",[1098,11035,1460],{"class":1133},[1098,11037,11038,11041,11043,11045],{"class":1100,"line":1652},[1098,11039,11040],{"class":1492},"                SecretId",[1098,11042,1229],{"class":1133},[1098,11044,10784],{"class":1232},[1098,11046,1873],{"class":1133},[1098,11048,11049,11052,11054,11056,11058,11061,11063,11066],{"class":1100,"line":1657},[1098,11050,11051],{"class":1492},"                SecretString",[1098,11053,1229],{"class":1133},[1098,11055,3934],{"class":1232},[1098,11057,1148],{"class":1133},[1098,11059,11060],{"class":1232},"dumps",[1098,11062,1255],{"class":1133},[1098,11064,11065],{"class":1232},"secret_value",[1098,11067,1342],{"class":1133},[1098,11069,11070],{"class":1100,"line":1675},[1098,11071,1512],{"class":1133},[1098,11073,11074],{"class":1100,"line":1680},[1098,11075,1518],{"class":1115},[1098,11077,11078],{"class":1100,"line":1695},[1098,11079,11080],{"class":1104},"            # Invalidate cache\n",[1098,11082,11083,11086,11088,11090,11092,11094,11096,11098],{"class":1100,"line":1714},[1098,11084,11085],{"class":1115},"            cache_key ",[1098,11087,1229],{"class":1133},[1098,11089,3867],{"class":1247},[1098,11091,10779],{"class":1336},[1098,11093,3874],{"class":3873},[1098,11095,10784],{"class":1115},[1098,11097,3879],{"class":3873},[1098,11099,5705],{"class":1336},[1098,11101,11102,11105,11107,11110,11112,11114],{"class":1100,"line":1728},[1098,11103,11104],{"class":1115},"            cache",[1098,11106,1148],{"class":1133},[1098,11108,11109],{"class":1232},"delete",[1098,11111,1255],{"class":1133},[1098,11113,10807],{"class":1232},[1098,11115,1342],{"class":1133},[1098,11117,11118],{"class":1100,"line":1746},[1098,11119,1518],{"class":1115},[1098,11121,11122,11124,11126,11128,11130],{"class":1100,"line":1760},[1098,11123,1683],{"class":1111},[1098,11125,9650],{"class":1814},[1098,11127,3423],{"class":1111},[1098,11129,3426],{"class":1115},[1098,11131,1441],{"class":1133},[1098,11133,11134,11136,11138,11140,11142,11145,11147,11149,11151,11153,11155,11157,11159,11161],{"class":1100,"line":1778},[1098,11135,1698],{"class":1111},[1098,11137,5421],{"class":1814},[1098,11139,1255],{"class":1133},[1098,11141,10257],{"class":1247},[1098,11143,11144],{"class":1336},"\"Failed to update secret ",[1098,11146,3874],{"class":3873},[1098,11148,10784],{"class":1232},[1098,11150,3879],{"class":3873},[1098,11152,10959],{"class":1336},[1098,11154,3874],{"class":3873},[1098,11156,3458],{"class":1232},[1098,11158,3879],{"class":3873},[1098,11160,5680],{"class":1336},[1098,11162,1342],{"class":1133},[1098,11164,11165],{"class":1100,"line":1783},[1098,11166,1220],{"emptyLinePlaceholder":1219},[1098,11168,11169],{"class":1100,"line":1793},[1098,11170,11171],{"class":1104},"# Kubernetes secrets integration\n",[1098,11173,11174,11176,11179],{"class":1100,"line":1803},[1098,11175,1248],{"class":1247},[1098,11177,11178],{"class":1251}," KubernetesSecretsManager",[1098,11180,1441],{"class":1133},[1098,11182,11183,11185,11188],{"class":1100,"line":1808},[1098,11184,1269],{"class":1268},[1098,11186,11187],{"class":1272},"Kubernetes secrets integration",[1098,11189,1276],{"class":1268},[1098,11191,11192],{"class":1100,"line":1818},[1098,11193,1282],{"class":1115},[1098,11195,11196,11198,11200,11202,11204],{"class":1100,"line":1832},[1098,11197,1288],{"class":1247},[1098,11199,5800],{"class":4766},[1098,11201,1255],{"class":1133},[1098,11203,1298],{"class":1297},[1098,11205,1262],{"class":1133},[1098,11207,11208,11211,11214,11216,11219,11221],{"class":1100,"line":1843},[1098,11209,11210],{"class":1111},"        from",[1098,11212,11213],{"class":1115}," kubernetes ",[1098,11215,1112],{"class":1111},[1098,11217,11218],{"class":1115}," client",[1098,11220,1134],{"class":1133},[1098,11222,11223],{"class":1115}," config\n",[1098,11225,11226],{"class":1100,"line":1854},[1098,11227,1395],{"class":1115},[1098,11229,11230,11232],{"class":1100,"line":1876},[1098,11231,1438],{"class":1111},[1098,11233,1441],{"class":1133},[1098,11235,11236,11239,11241,11244],{"class":1100,"line":1896},[1098,11237,11238],{"class":1115},"            config",[1098,11240,1148],{"class":1133},[1098,11242,11243],{"class":1232},"load_incluster_config",[1098,11245,1236],{"class":1133},[1098,11247,11248,11250],{"class":1100,"line":1916},[1098,11249,1683],{"class":1111},[1098,11251,1441],{"class":1133},[1098,11253,11254,11256,11258,11261],{"class":1100,"line":1961},[1098,11255,11238],{"class":1115},[1098,11257,1148],{"class":1133},[1098,11259,11260],{"class":1232},"load_kube_config",[1098,11262,1236],{"class":1133},[1098,11264,11265],{"class":1100,"line":1982},[1098,11266,1395],{"class":1115},[1098,11268,11269,11271,11273,11276,11278,11280,11282,11285],{"class":1100,"line":2002},[1098,11270,5815],{"class":3697},[1098,11272,1148],{"class":1133},[1098,11274,11275],{"class":1598},"v1",[1098,11277,5822],{"class":1133},[1098,11279,11218],{"class":1115},[1098,11281,1148],{"class":1133},[1098,11283,11284],{"class":1232},"CoreV1Api",[1098,11286,1236],{"class":1133},[1098,11288,11289],{"class":1100,"line":2008},[1098,11290,1282],{"class":1115},[1098,11292,11293,11295,11297,11299,11301,11303,11305,11307,11310,11312,11314,11317,11319],{"class":1100,"line":2013},[1098,11294,1288],{"class":1247},[1098,11296,10737],{"class":1291},[1098,11298,1255],{"class":1133},[1098,11300,1298],{"class":1297},[1098,11302,1134],{"class":1133},[1098,11304,10746],{"class":1303},[1098,11306,1134],{"class":1133},[1098,11308,11309],{"class":1303}," namespace",[1098,11311,1229],{"class":1351},[1098,11313,1333],{"class":1332},[1098,11315,11316],{"class":1336},"default",[1098,11318,1333],{"class":1332},[1098,11320,1262],{"class":1133},[1098,11322,11323,11325,11328],{"class":1100,"line":2028},[1098,11324,1835],{"class":1268},[1098,11326,11327],{"class":1272},"Get Kubernetes secret",[1098,11329,1276],{"class":1268},[1098,11331,11332,11334],{"class":1100,"line":2038},[1098,11333,1438],{"class":1111},[1098,11335,1441],{"class":1133},[1098,11337,11338,11341,11343,11345,11347,11349,11351,11354],{"class":1100,"line":2052},[1098,11339,11340],{"class":1115},"            secret ",[1098,11342,1229],{"class":1133},[1098,11344,3698],{"class":3697},[1098,11346,1148],{"class":1133},[1098,11348,11275],{"class":1598},[1098,11350,1148],{"class":1133},[1098,11352,11353],{"class":1232},"read_namespaced_secret",[1098,11355,1460],{"class":1133},[1098,11357,11358,11361,11363,11365],{"class":1100,"line":2067},[1098,11359,11360],{"class":1492},"                name",[1098,11362,1229],{"class":1133},[1098,11364,10784],{"class":1232},[1098,11366,1873],{"class":1133},[1098,11368,11369,11372,11374],{"class":1100,"line":2073},[1098,11370,11371],{"class":1492},"                namespace",[1098,11373,1229],{"class":1133},[1098,11375,11376],{"class":1232},"namespace\n",[1098,11378,11379],{"class":1100,"line":2078},[1098,11380,1512],{"class":1133},[1098,11382,11383],{"class":1100,"line":2085},[1098,11384,1518],{"class":1115},[1098,11386,11387],{"class":1100,"line":2099},[1098,11388,11389],{"class":1104},"            # Decode base64 encoded values\n",[1098,11391,11392,11395,11397],{"class":1100,"line":2109},[1098,11393,11394],{"class":1115},"            decoded_data ",[1098,11396,1229],{"class":1133},[1098,11398,8252],{"class":1133},[1098,11400,11401,11404,11407,11409,11411,11413,11416,11418,11420,11422,11424],{"class":1100,"line":2118},[1098,11402,11403],{"class":1111},"            for",[1098,11405,11406],{"class":1115}," key",[1098,11408,1134],{"class":1133},[1098,11410,8028],{"class":1115},[1098,11412,5027],{"class":1111},[1098,11414,11415],{"class":1115}," secret",[1098,11417,1148],{"class":1133},[1098,11419,2704],{"class":1598},[1098,11421,1148],{"class":1133},[1098,11423,8037],{"class":1232},[1098,11425,4744],{"class":1133},[1098,11427,11428,11431,11433,11435,11437,11439,11441,11443,11445,11447,11449,11451,11453],{"class":1100,"line":2137},[1098,11429,11430],{"class":1115},"                decoded_data",[1098,11432,3327],{"class":1133},[1098,11434,7218],{"class":1115},[1098,11436,6168],{"class":1133},[1098,11438,5822],{"class":1133},[1098,11440,10121],{"class":1115},[1098,11442,1148],{"class":1133},[1098,11444,10188],{"class":1232},[1098,11446,1255],{"class":1133},[1098,11448,8051],{"class":1232},[1098,11450,4738],{"class":1133},[1098,11452,1457],{"class":1232},[1098,11454,1236],{"class":1133},[1098,11456,11457],{"class":1100,"line":2176},[1098,11458,1518],{"class":1115},[1098,11460,11461,11463],{"class":1100,"line":2195},[1098,11462,1385],{"class":1111},[1098,11464,11465],{"class":1115}," decoded_data\n",[1098,11467,11468],{"class":1100,"line":2213},[1098,11469,1518],{"class":1115},[1098,11471,11472,11474,11476,11478,11480],{"class":1100,"line":2218},[1098,11473,1683],{"class":1111},[1098,11475,9650],{"class":1814},[1098,11477,3423],{"class":1111},[1098,11479,3426],{"class":1115},[1098,11481,1441],{"class":1133},[1098,11483,11484,11486,11488,11490,11492,11494,11496,11498,11500,11502,11504,11506,11508,11510],{"class":1100,"line":2223},[1098,11485,1698],{"class":1111},[1098,11487,5421],{"class":1814},[1098,11489,1255],{"class":1133},[1098,11491,10257],{"class":1247},[1098,11493,10950],{"class":1336},[1098,11495,3874],{"class":3873},[1098,11497,10784],{"class":1232},[1098,11499,3879],{"class":3873},[1098,11501,10959],{"class":1336},[1098,11503,3874],{"class":3873},[1098,11505,3458],{"class":1232},[1098,11507,3879],{"class":3873},[1098,11509,5680],{"class":1336},[1098,11511,1342],{"class":1133},[1098,11513,11514],{"class":1100,"line":2236},[1098,11515,1220],{"emptyLinePlaceholder":1219},[1098,11517,11518],{"class":1100,"line":2245},[1098,11519,11520],{"class":1104},"# Environment-based secrets\n",[1098,11522,11523,11525,11528],{"class":1100,"line":2258},[1098,11524,1248],{"class":1247},[1098,11526,11527],{"class":1251}," EnvironmentSecretsManager",[1098,11529,1441],{"class":1133},[1098,11531,11532,11534,11537],{"class":1100,"line":2271},[1098,11533,1269],{"class":1268},[1098,11535,11536],{"class":1272},"Environment variable based secrets",[1098,11538,1276],{"class":1268},[1098,11540,11541],{"class":1100,"line":2276},[1098,11542,1282],{"class":1115},[1098,11544,11545,11547],{"class":1100,"line":2281},[1098,11546,1811],{"class":1133},[1098,11548,1815],{"class":1814},[1098,11550,11551,11553,11555,11557,11559],{"class":1100,"line":2288},[1098,11552,1288],{"class":1247},[1098,11554,10737],{"class":1291},[1098,11556,1255],{"class":1133},[1098,11558,10784],{"class":1303},[1098,11560,1262],{"class":1133},[1098,11562,11563,11565,11568],{"class":1100,"line":2316},[1098,11564,1835],{"class":1268},[1098,11566,11567],{"class":1272},"Get secret from environment variables",[1098,11569,1276],{"class":1268},[1098,11571,11572,11575],{"class":1100,"line":2326},[1098,11573,11574],{"class":1111},"        import",[1098,11576,11577],{"class":1115}," os\n",[1098,11579,11580],{"class":1100,"line":2333},[1098,11581,1395],{"class":1115},[1098,11583,11584,11586,11588,11591,11593,11596,11598,11600],{"class":1100,"line":2348},[1098,11585,10793],{"class":1115},[1098,11587,1229],{"class":1133},[1098,11589,11590],{"class":1115}," os",[1098,11592,1148],{"class":1133},[1098,11594,11595],{"class":1232},"getenv",[1098,11597,1255],{"class":1133},[1098,11599,10784],{"class":1232},[1098,11601,1342],{"class":1133},[1098,11603,11604,11606,11608,11610,11612],{"class":1100,"line":2357},[1098,11605,1348],{"class":1111},[1098,11607,10820],{"class":1115},[1098,11609,9576],{"class":1351},[1098,11611,7197],{"class":1388},[1098,11613,1441],{"class":1133},[1098,11615,11616,11618,11620,11622,11624,11627,11629,11631,11633,11636],{"class":1100,"line":2370},[1098,11617,1698],{"class":1111},[1098,11619,5421],{"class":1814},[1098,11621,1255],{"class":1133},[1098,11623,10257],{"class":1247},[1098,11625,11626],{"class":1336},"\"Secret ",[1098,11628,3874],{"class":3873},[1098,11630,10784],{"class":1232},[1098,11632,3879],{"class":3873},[1098,11634,11635],{"class":1336}," not found in environment\"",[1098,11637,1342],{"class":1133},[1098,11639,11640],{"class":1100,"line":2385},[1098,11641,1395],{"class":1115},[1098,11643,11644,11646],{"class":1100,"line":2390},[1098,11645,1438],{"class":1111},[1098,11647,1441],{"class":1133},[1098,11649,11650],{"class":1100,"line":2395},[1098,11651,11652],{"class":1104},"            # Try to parse as JSON\n",[1098,11654,11655,11657,11659,11661,11663,11665,11667],{"class":1100,"line":2424},[1098,11656,1385],{"class":1111},[1098,11658,10872],{"class":1115},[1098,11660,1148],{"class":1133},[1098,11662,10877],{"class":1232},[1098,11664,1255],{"class":1133},[1098,11666,11065],{"class":1232},[1098,11668,1342],{"class":1133},[1098,11670,11671,11673,11675,11677,11680],{"class":1100,"line":2446},[1098,11672,1683],{"class":1111},[1098,11674,10872],{"class":1115},[1098,11676,1148],{"class":1133},[1098,11678,11679],{"class":1598},"JSONDecodeError",[1098,11681,1441],{"class":1133},[1098,11683,11684],{"class":1100,"line":2451},[1098,11685,11686],{"class":1104},"            # Return as string if not JSON\n",[1098,11688,11689,11691],{"class":1100,"line":2459},[1098,11690,1385],{"class":1111},[1098,11692,10980],{"class":1115},[1030,11694,1060],{"id":11695},"network-security",[1035,11697,11699],{"id":11698},"_1-network-policies","1. Network Policies",[1088,11701,11705],{"className":11702,"code":11703,"language":11704,"meta":1093,"style":1093},"language-yaml shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# k8s/network-policies.yaml\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: microservices-network-policy\n  namespace: microservices\nspec:\n  podSelector: {}\n  policyTypes:\n  - Ingress\n  - Egress\n  \n  ingress:\n  # Allow ingress from API Gateway\n  - from:\n    - namespaceSelector:\n        matchLabels:\n          name: ingress-nginx\n    ports:\n    - protocol: TCP\n      port: 8000\n  \n  # Allow inter-service communication\n  - from:\n    - podSelector:\n        matchLabels:\n          app: user-service\n    - podSelector:\n        matchLabels:\n          app: product-service\n    - podSelector:\n        matchLabels:\n          app: order-service\n    ports:\n    - protocol: TCP\n      port: 8000\n  \n  egress:\n  # Allow egress to databases\n  - to:\n    - podSelector:\n        matchLabels:\n          app: postgresql\n    ports:\n    - protocol: TCP\n      port: 5432\n  \n  # Allow egress to Redis\n  - to:\n    - podSelector:\n        matchLabels:\n          app: redis\n    ports:\n    - protocol: TCP\n      port: 6379\n  \n  # Allow DNS resolution\n  - to: []\n    ports:\n    - protocol: UDP\n      port: 53\n  \n  # Allow HTTPS egress for external APIs\n  - to: []\n    ports:\n    - protocol: TCP\n      port: 443\n\n---\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: database-network-policy\n  namespace: microservices\nspec:\n  podSelector:\n    matchLabels:\n      app: postgresql\n  policyTypes:\n  - Ingress\n  \n  ingress:\n  # Only allow access from microservices\n  - from:\n    - podSelector:\n        matchLabels:\n          app: user-service\n    - podSelector:\n        matchLabels:\n          app: product-service\n    - podSelector:\n        matchLabels:\n          app: order-service\n    ports:\n    - protocol: TCP\n      port: 5432\n","yaml",[1095,11706,11707,11712,11723,11733,11740,11750,11760,11767,11776,11783,11791,11798,11803,11810,11815,11824,11834,11841,11851,11858,11870,11880,11884,11889,11897,11906,11912,11922,11930,11936,11945,11953,11959,11968,11974,11984,11992,11996,12003,12008,12017,12025,12031,12040,12046,12056,12065,12069,12074,12082,12090,12096,12105,12111,12121,12130,12134,12139,12149,12155,12166,12175,12179,12184,12194,12200,12210,12219,12223,12228,12236,12244,12250,12259,12267,12273,12279,12286,12295,12301,12307,12311,12317,12322,12330,12338,12344,12352,12360,12366,12374,12382,12388,12396,12402,12412],{"__ignoreMap":1093},[1098,11708,11709],{"class":1100,"line":1101},[1098,11710,11711],{"class":1104},"# k8s/network-policies.yaml\n",[1098,11713,11714,11718,11720],{"class":1100,"line":1108},[1098,11715,11717],{"class":11716},"suXOh","apiVersion",[1098,11719,1864],{"class":1133},[1098,11721,11722],{"class":1336}," networking.k8s.io/v1\n",[1098,11724,11725,11728,11730],{"class":1100,"line":1119},[1098,11726,11727],{"class":11716},"kind",[1098,11729,1864],{"class":1133},[1098,11731,11732],{"class":1336}," NetworkPolicy\n",[1098,11734,11735,11738],{"class":1100,"line":1140},[1098,11736,11737],{"class":11716},"metadata",[1098,11739,1441],{"class":1133},[1098,11741,11742,11745,11747],{"class":1100,"line":1159},[1098,11743,11744],{"class":11716},"  name",[1098,11746,1864],{"class":1133},[1098,11748,11749],{"class":1336}," microservices-network-policy\n",[1098,11751,11752,11755,11757],{"class":1100,"line":1181},[1098,11753,11754],{"class":11716},"  namespace",[1098,11756,1864],{"class":1133},[1098,11758,11759],{"class":1336}," microservices\n",[1098,11761,11762,11765],{"class":1100,"line":1199},[1098,11763,11764],{"class":11716},"spec",[1098,11766,1441],{"class":1133},[1098,11768,11769,11772,11774],{"class":1100,"line":1216},[1098,11770,11771],{"class":11716},"  podSelector",[1098,11773,1864],{"class":1133},[1098,11775,8252],{"class":1133},[1098,11777,11778,11781],{"class":1100,"line":1223},[1098,11779,11780],{"class":11716},"  policyTypes",[1098,11782,1441],{"class":1133},[1098,11784,11785,11788],{"class":1100,"line":1239},[1098,11786,11787],{"class":1133},"  -",[1098,11789,11790],{"class":1336}," Ingress\n",[1098,11792,11793,11795],{"class":1100,"line":1244},[1098,11794,11787],{"class":1133},[1098,11796,11797],{"class":1336}," Egress\n",[1098,11799,11800],{"class":1100,"line":1265},[1098,11801,11802],{"class":1115},"  \n",[1098,11804,11805,11808],{"class":1100,"line":1279},[1098,11806,11807],{"class":11716},"  ingress",[1098,11809,1441],{"class":1133},[1098,11811,11812],{"class":1100,"line":1285},[1098,11813,11814],{"class":1104},"  # Allow ingress from API Gateway\n",[1098,11816,11817,11819,11822],{"class":1100,"line":1309},[1098,11818,11787],{"class":1133},[1098,11820,11821],{"class":11716}," from",[1098,11823,1441],{"class":1133},[1098,11825,11826,11829,11832],{"class":1100,"line":1345},[1098,11827,11828],{"class":1133},"    -",[1098,11830,11831],{"class":11716}," namespaceSelector",[1098,11833,1441],{"class":1133},[1098,11835,11836,11839],{"class":1100,"line":1382},[1098,11837,11838],{"class":11716},"        matchLabels",[1098,11840,1441],{"class":1133},[1098,11842,11843,11846,11848],{"class":1100,"line":1392},[1098,11844,11845],{"class":11716},"          name",[1098,11847,1864],{"class":1133},[1098,11849,11850],{"class":1336}," ingress-nginx\n",[1098,11852,11853,11856],{"class":1100,"line":1398},[1098,11854,11855],{"class":11716},"    ports",[1098,11857,1441],{"class":1133},[1098,11859,11860,11862,11865,11867],{"class":1100,"line":1430},[1098,11861,11828],{"class":1133},[1098,11863,11864],{"class":11716}," protocol",[1098,11866,1864],{"class":1133},[1098,11868,11869],{"class":1336}," TCP\n",[1098,11871,11872,11875,11877],{"class":1100,"line":1435},[1098,11873,11874],{"class":11716},"      port",[1098,11876,1864],{"class":1133},[1098,11878,11879],{"class":1423}," 8000\n",[1098,11881,11882],{"class":1100,"line":1444},[1098,11883,11802],{"class":1115},[1098,11885,11886],{"class":1100,"line":1463},[1098,11887,11888],{"class":1104},"  # Allow inter-service communication\n",[1098,11890,11891,11893,11895],{"class":1100,"line":1474},[1098,11892,11787],{"class":1133},[1098,11894,11821],{"class":11716},[1098,11896,1441],{"class":1133},[1098,11898,11899,11901,11904],{"class":1100,"line":1489},[1098,11900,11828],{"class":1133},[1098,11902,11903],{"class":11716}," podSelector",[1098,11905,1441],{"class":1133},[1098,11907,11908,11910],{"class":1100,"line":1509},[1098,11909,11838],{"class":11716},[1098,11911,1441],{"class":1133},[1098,11913,11914,11917,11919],{"class":1100,"line":1515},[1098,11915,11916],{"class":11716},"          app",[1098,11918,1864],{"class":1133},[1098,11920,11921],{"class":1336}," user-service\n",[1098,11923,11924,11926,11928],{"class":1100,"line":1521},[1098,11925,11828],{"class":1133},[1098,11927,11903],{"class":11716},[1098,11929,1441],{"class":1133},[1098,11931,11932,11934],{"class":1100,"line":1547},[1098,11933,11838],{"class":11716},[1098,11935,1441],{"class":1133},[1098,11937,11938,11940,11942],{"class":1100,"line":1560},[1098,11939,11916],{"class":11716},[1098,11941,1864],{"class":1133},[1098,11943,11944],{"class":1336}," product-service\n",[1098,11946,11947,11949,11951],{"class":1100,"line":1580},[1098,11948,11828],{"class":1133},[1098,11950,11903],{"class":11716},[1098,11952,1441],{"class":1133},[1098,11954,11955,11957],{"class":1100,"line":1585},[1098,11956,11838],{"class":11716},[1098,11958,1441],{"class":1133},[1098,11960,11961,11963,11965],{"class":1100,"line":1617},[1098,11962,11916],{"class":11716},[1098,11964,1864],{"class":1133},[1098,11966,11967],{"class":1336}," order-service\n",[1098,11969,11970,11972],{"class":1100,"line":1634},[1098,11971,11855],{"class":11716},[1098,11973,1441],{"class":1133},[1098,11975,11976,11978,11980,11982],{"class":1100,"line":1652},[1098,11977,11828],{"class":1133},[1098,11979,11864],{"class":11716},[1098,11981,1864],{"class":1133},[1098,11983,11869],{"class":1336},[1098,11985,11986,11988,11990],{"class":1100,"line":1657},[1098,11987,11874],{"class":11716},[1098,11989,1864],{"class":1133},[1098,11991,11879],{"class":1423},[1098,11993,11994],{"class":1100,"line":1675},[1098,11995,11802],{"class":1115},[1098,11997,11998,12001],{"class":1100,"line":1680},[1098,11999,12000],{"class":11716},"  egress",[1098,12002,1441],{"class":1133},[1098,12004,12005],{"class":1100,"line":1695},[1098,12006,12007],{"class":1104},"  # Allow egress to databases\n",[1098,12009,12010,12012,12015],{"class":1100,"line":1714},[1098,12011,11787],{"class":1133},[1098,12013,12014],{"class":11716}," to",[1098,12016,1441],{"class":1133},[1098,12018,12019,12021,12023],{"class":1100,"line":1728},[1098,12020,11828],{"class":1133},[1098,12022,11903],{"class":11716},[1098,12024,1441],{"class":1133},[1098,12026,12027,12029],{"class":1100,"line":1746},[1098,12028,11838],{"class":11716},[1098,12030,1441],{"class":1133},[1098,12032,12033,12035,12037],{"class":1100,"line":1760},[1098,12034,11916],{"class":11716},[1098,12036,1864],{"class":1133},[1098,12038,12039],{"class":1336}," postgresql\n",[1098,12041,12042,12044],{"class":1100,"line":1778},[1098,12043,11855],{"class":11716},[1098,12045,1441],{"class":1133},[1098,12047,12048,12050,12052,12054],{"class":1100,"line":1783},[1098,12049,11828],{"class":1133},[1098,12051,11864],{"class":11716},[1098,12053,1864],{"class":1133},[1098,12055,11869],{"class":1336},[1098,12057,12058,12060,12062],{"class":1100,"line":1793},[1098,12059,11874],{"class":11716},[1098,12061,1864],{"class":1133},[1098,12063,12064],{"class":1423}," 5432\n",[1098,12066,12067],{"class":1100,"line":1803},[1098,12068,11802],{"class":1115},[1098,12070,12071],{"class":1100,"line":1808},[1098,12072,12073],{"class":1104},"  # Allow egress to Redis\n",[1098,12075,12076,12078,12080],{"class":1100,"line":1818},[1098,12077,11787],{"class":1133},[1098,12079,12014],{"class":11716},[1098,12081,1441],{"class":1133},[1098,12083,12084,12086,12088],{"class":1100,"line":1832},[1098,12085,11828],{"class":1133},[1098,12087,11903],{"class":11716},[1098,12089,1441],{"class":1133},[1098,12091,12092,12094],{"class":1100,"line":1843},[1098,12093,11838],{"class":11716},[1098,12095,1441],{"class":1133},[1098,12097,12098,12100,12102],{"class":1100,"line":1854},[1098,12099,11916],{"class":11716},[1098,12101,1864],{"class":1133},[1098,12103,12104],{"class":1336}," redis\n",[1098,12106,12107,12109],{"class":1100,"line":1876},[1098,12108,11855],{"class":11716},[1098,12110,1441],{"class":1133},[1098,12112,12113,12115,12117,12119],{"class":1100,"line":1896},[1098,12114,11828],{"class":1133},[1098,12116,11864],{"class":11716},[1098,12118,1864],{"class":1133},[1098,12120,11869],{"class":1336},[1098,12122,12123,12125,12127],{"class":1100,"line":1916},[1098,12124,11874],{"class":11716},[1098,12126,1864],{"class":1133},[1098,12128,12129],{"class":1423}," 6379\n",[1098,12131,12132],{"class":1100,"line":1961},[1098,12133,11802],{"class":1115},[1098,12135,12136],{"class":1100,"line":1982},[1098,12137,12138],{"class":1104},"  # Allow DNS resolution\n",[1098,12140,12141,12143,12145,12147],{"class":1100,"line":2002},[1098,12142,11787],{"class":1133},[1098,12144,12014],{"class":11716},[1098,12146,1864],{"class":1133},[1098,12148,4323],{"class":1133},[1098,12150,12151,12153],{"class":1100,"line":2008},[1098,12152,11855],{"class":11716},[1098,12154,1441],{"class":1133},[1098,12156,12157,12159,12161,12163],{"class":1100,"line":2013},[1098,12158,11828],{"class":1133},[1098,12160,11864],{"class":11716},[1098,12162,1864],{"class":1133},[1098,12164,12165],{"class":1336}," UDP\n",[1098,12167,12168,12170,12172],{"class":1100,"line":2028},[1098,12169,11874],{"class":11716},[1098,12171,1864],{"class":1133},[1098,12173,12174],{"class":1423}," 53\n",[1098,12176,12177],{"class":1100,"line":2038},[1098,12178,11802],{"class":1115},[1098,12180,12181],{"class":1100,"line":2052},[1098,12182,12183],{"class":1104},"  # Allow HTTPS egress for external APIs\n",[1098,12185,12186,12188,12190,12192],{"class":1100,"line":2067},[1098,12187,11787],{"class":1133},[1098,12189,12014],{"class":11716},[1098,12191,1864],{"class":1133},[1098,12193,4323],{"class":1133},[1098,12195,12196,12198],{"class":1100,"line":2073},[1098,12197,11855],{"class":11716},[1098,12199,1441],{"class":1133},[1098,12201,12202,12204,12206,12208],{"class":1100,"line":2078},[1098,12203,11828],{"class":1133},[1098,12205,11864],{"class":11716},[1098,12207,1864],{"class":1133},[1098,12209,11869],{"class":1336},[1098,12211,12212,12214,12216],{"class":1100,"line":2085},[1098,12213,11874],{"class":11716},[1098,12215,1864],{"class":1133},[1098,12217,12218],{"class":1423}," 443\n",[1098,12220,12221],{"class":1100,"line":2099},[1098,12222,1220],{"emptyLinePlaceholder":1219},[1098,12224,12225],{"class":1100,"line":2109},[1098,12226,12227],{"class":1258},"---\n",[1098,12229,12230,12232,12234],{"class":1100,"line":2118},[1098,12231,11717],{"class":11716},[1098,12233,1864],{"class":1133},[1098,12235,11722],{"class":1336},[1098,12237,12238,12240,12242],{"class":1100,"line":2137},[1098,12239,11727],{"class":11716},[1098,12241,1864],{"class":1133},[1098,12243,11732],{"class":1336},[1098,12245,12246,12248],{"class":1100,"line":2176},[1098,12247,11737],{"class":11716},[1098,12249,1441],{"class":1133},[1098,12251,12252,12254,12256],{"class":1100,"line":2195},[1098,12253,11744],{"class":11716},[1098,12255,1864],{"class":1133},[1098,12257,12258],{"class":1336}," database-network-policy\n",[1098,12260,12261,12263,12265],{"class":1100,"line":2213},[1098,12262,11754],{"class":11716},[1098,12264,1864],{"class":1133},[1098,12266,11759],{"class":1336},[1098,12268,12269,12271],{"class":1100,"line":2218},[1098,12270,11764],{"class":11716},[1098,12272,1441],{"class":1133},[1098,12274,12275,12277],{"class":1100,"line":2223},[1098,12276,11771],{"class":11716},[1098,12278,1441],{"class":1133},[1098,12280,12281,12284],{"class":1100,"line":2236},[1098,12282,12283],{"class":11716},"    matchLabels",[1098,12285,1441],{"class":1133},[1098,12287,12288,12291,12293],{"class":1100,"line":2245},[1098,12289,12290],{"class":11716},"      app",[1098,12292,1864],{"class":1133},[1098,12294,12039],{"class":1336},[1098,12296,12297,12299],{"class":1100,"line":2258},[1098,12298,11780],{"class":11716},[1098,12300,1441],{"class":1133},[1098,12302,12303,12305],{"class":1100,"line":2271},[1098,12304,11787],{"class":1133},[1098,12306,11790],{"class":1336},[1098,12308,12309],{"class":1100,"line":2276},[1098,12310,11802],{"class":1115},[1098,12312,12313,12315],{"class":1100,"line":2281},[1098,12314,11807],{"class":11716},[1098,12316,1441],{"class":1133},[1098,12318,12319],{"class":1100,"line":2288},[1098,12320,12321],{"class":1104},"  # Only allow access from microservices\n",[1098,12323,12324,12326,12328],{"class":1100,"line":2316},[1098,12325,11787],{"class":1133},[1098,12327,11821],{"class":11716},[1098,12329,1441],{"class":1133},[1098,12331,12332,12334,12336],{"class":1100,"line":2326},[1098,12333,11828],{"class":1133},[1098,12335,11903],{"class":11716},[1098,12337,1441],{"class":1133},[1098,12339,12340,12342],{"class":1100,"line":2333},[1098,12341,11838],{"class":11716},[1098,12343,1441],{"class":1133},[1098,12345,12346,12348,12350],{"class":1100,"line":2348},[1098,12347,11916],{"class":11716},[1098,12349,1864],{"class":1133},[1098,12351,11921],{"class":1336},[1098,12353,12354,12356,12358],{"class":1100,"line":2357},[1098,12355,11828],{"class":1133},[1098,12357,11903],{"class":11716},[1098,12359,1441],{"class":1133},[1098,12361,12362,12364],{"class":1100,"line":2370},[1098,12363,11838],{"class":11716},[1098,12365,1441],{"class":1133},[1098,12367,12368,12370,12372],{"class":1100,"line":2385},[1098,12369,11916],{"class":11716},[1098,12371,1864],{"class":1133},[1098,12373,11944],{"class":1336},[1098,12375,12376,12378,12380],{"class":1100,"line":2390},[1098,12377,11828],{"class":1133},[1098,12379,11903],{"class":11716},[1098,12381,1441],{"class":1133},[1098,12383,12384,12386],{"class":1100,"line":2395},[1098,12385,11838],{"class":11716},[1098,12387,1441],{"class":1133},[1098,12389,12390,12392,12394],{"class":1100,"line":2424},[1098,12391,11916],{"class":11716},[1098,12393,1864],{"class":1133},[1098,12395,11967],{"class":1336},[1098,12397,12398,12400],{"class":1100,"line":2446},[1098,12399,11855],{"class":11716},[1098,12401,1441],{"class":1133},[1098,12403,12404,12406,12408,12410],{"class":1100,"line":2451},[1098,12405,11828],{"class":1133},[1098,12407,11864],{"class":11716},[1098,12409,1864],{"class":1133},[1098,12411,11869],{"class":1336},[1098,12413,12414,12416,12418],{"class":1100,"line":2459},[1098,12415,11874],{"class":11716},[1098,12417,1864],{"class":1133},[1098,12419,12064],{"class":1423},[1035,12421,12423],{"id":12422},"_2-service-mesh-security-istio","2. Service Mesh Security (Istio)",[1088,12425,12427],{"className":11702,"code":12426,"language":11704,"meta":1093,"style":1093},"# istio/security-policies.yaml\napiVersion: security.istio.io/v1beta1\nkind: PeerAuthentication\nmetadata:\n  name: default\n  namespace: microservices\nspec:\n  mtls:\n    mode: STRICT\n\n---\napiVersion: security.istio.io/v1beta1\nkind: AuthorizationPolicy\nmetadata:\n  name: user-service-authz\n  namespace: microservices\nspec:\n  selector:\n    matchLabels:\n      app: user-service\n  rules:\n  - from:\n    - source:\n        principals: [\"cluster.local/ns/microservices/sa/order-service\"]\n    - source:\n        principals: [\"cluster.local/ns/microservices/sa/api-gateway\"]\n    to:\n    - operation:\n        methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\"]\n        paths: [\"/api/v1/users/*\"]\n\n---\napiVersion: security.istio.io/v1beta1\nkind: RequestAuthentication\nmetadata:\n  name: jwt-auth\n  namespace: microservices\nspec:\n  selector:\n    matchLabels:\n      app: user-service\n  jwtRules:\n  - issuer: \"https://auth.example.com\"\n    jwksUri: \"https://auth.example.com/.well-known/jwks.json\"\n    audiences:\n    - \"microservices-api\"\n",[1095,12428,12429,12434,12443,12452,12458,12467,12475,12481,12488,12498,12502,12506,12514,12523,12529,12538,12546,12552,12559,12565,12573,12580,12588,12597,12615,12623,12640,12647,12656,12700,12718,12722,12726,12734,12743,12749,12758,12766,12772,12778,12784,12792,12799,12815,12829,12836],{"__ignoreMap":1093},[1098,12430,12431],{"class":1100,"line":1101},[1098,12432,12433],{"class":1104},"# istio/security-policies.yaml\n",[1098,12435,12436,12438,12440],{"class":1100,"line":1108},[1098,12437,11717],{"class":11716},[1098,12439,1864],{"class":1133},[1098,12441,12442],{"class":1336}," security.istio.io/v1beta1\n",[1098,12444,12445,12447,12449],{"class":1100,"line":1119},[1098,12446,11727],{"class":11716},[1098,12448,1864],{"class":1133},[1098,12450,12451],{"class":1336}," PeerAuthentication\n",[1098,12453,12454,12456],{"class":1100,"line":1140},[1098,12455,11737],{"class":11716},[1098,12457,1441],{"class":1133},[1098,12459,12460,12462,12464],{"class":1100,"line":1159},[1098,12461,11744],{"class":11716},[1098,12463,1864],{"class":1133},[1098,12465,12466],{"class":1336}," default\n",[1098,12468,12469,12471,12473],{"class":1100,"line":1181},[1098,12470,11754],{"class":11716},[1098,12472,1864],{"class":1133},[1098,12474,11759],{"class":1336},[1098,12476,12477,12479],{"class":1100,"line":1199},[1098,12478,11764],{"class":11716},[1098,12480,1441],{"class":1133},[1098,12482,12483,12486],{"class":1100,"line":1216},[1098,12484,12485],{"class":11716},"  mtls",[1098,12487,1441],{"class":1133},[1098,12489,12490,12493,12495],{"class":1100,"line":1223},[1098,12491,12492],{"class":11716},"    mode",[1098,12494,1864],{"class":1133},[1098,12496,12497],{"class":1336}," STRICT\n",[1098,12499,12500],{"class":1100,"line":1239},[1098,12501,1220],{"emptyLinePlaceholder":1219},[1098,12503,12504],{"class":1100,"line":1244},[1098,12505,12227],{"class":1258},[1098,12507,12508,12510,12512],{"class":1100,"line":1265},[1098,12509,11717],{"class":11716},[1098,12511,1864],{"class":1133},[1098,12513,12442],{"class":1336},[1098,12515,12516,12518,12520],{"class":1100,"line":1279},[1098,12517,11727],{"class":11716},[1098,12519,1864],{"class":1133},[1098,12521,12522],{"class":1336}," AuthorizationPolicy\n",[1098,12524,12525,12527],{"class":1100,"line":1285},[1098,12526,11737],{"class":11716},[1098,12528,1441],{"class":1133},[1098,12530,12531,12533,12535],{"class":1100,"line":1309},[1098,12532,11744],{"class":11716},[1098,12534,1864],{"class":1133},[1098,12536,12537],{"class":1336}," user-service-authz\n",[1098,12539,12540,12542,12544],{"class":1100,"line":1345},[1098,12541,11754],{"class":11716},[1098,12543,1864],{"class":1133},[1098,12545,11759],{"class":1336},[1098,12547,12548,12550],{"class":1100,"line":1382},[1098,12549,11764],{"class":11716},[1098,12551,1441],{"class":1133},[1098,12553,12554,12557],{"class":1100,"line":1392},[1098,12555,12556],{"class":11716},"  selector",[1098,12558,1441],{"class":1133},[1098,12560,12561,12563],{"class":1100,"line":1398},[1098,12562,12283],{"class":11716},[1098,12564,1441],{"class":1133},[1098,12566,12567,12569,12571],{"class":1100,"line":1430},[1098,12568,12290],{"class":11716},[1098,12570,1864],{"class":1133},[1098,12572,11921],{"class":1336},[1098,12574,12575,12578],{"class":1100,"line":1435},[1098,12576,12577],{"class":11716},"  rules",[1098,12579,1441],{"class":1133},[1098,12581,12582,12584,12586],{"class":1100,"line":1444},[1098,12583,11787],{"class":1133},[1098,12585,11821],{"class":11716},[1098,12587,1441],{"class":1133},[1098,12589,12590,12592,12595],{"class":1100,"line":1463},[1098,12591,11828],{"class":1133},[1098,12593,12594],{"class":11716}," source",[1098,12596,1441],{"class":1133},[1098,12598,12599,12602,12604,12606,12608,12611,12613],{"class":1100,"line":1474},[1098,12600,12601],{"class":11716},"        principals",[1098,12603,1864],{"class":1133},[1098,12605,4538],{"class":1133},[1098,12607,5680],{"class":1332},[1098,12609,12610],{"class":1336},"cluster.local/ns/microservices/sa/order-service",[1098,12612,5680],{"class":1332},[1098,12614,1427],{"class":1133},[1098,12616,12617,12619,12621],{"class":1100,"line":1489},[1098,12618,11828],{"class":1133},[1098,12620,12594],{"class":11716},[1098,12622,1441],{"class":1133},[1098,12624,12625,12627,12629,12631,12633,12636,12638],{"class":1100,"line":1509},[1098,12626,12601],{"class":11716},[1098,12628,1864],{"class":1133},[1098,12630,4538],{"class":1133},[1098,12632,5680],{"class":1332},[1098,12634,12635],{"class":1336},"cluster.local/ns/microservices/sa/api-gateway",[1098,12637,5680],{"class":1332},[1098,12639,1427],{"class":1133},[1098,12641,12642,12645],{"class":1100,"line":1515},[1098,12643,12644],{"class":11716},"    to",[1098,12646,1441],{"class":1133},[1098,12648,12649,12651,12654],{"class":1100,"line":1521},[1098,12650,11828],{"class":1133},[1098,12652,12653],{"class":11716}," operation",[1098,12655,1441],{"class":1133},[1098,12657,12658,12661,12663,12665,12667,12670,12672,12674,12677,12679,12681,12683,12685,12688,12690,12692,12694,12696,12698],{"class":1100,"line":1547},[1098,12659,12660],{"class":11716},"        methods",[1098,12662,1864],{"class":1133},[1098,12664,4538],{"class":1133},[1098,12666,5680],{"class":1332},[1098,12668,12669],{"class":1336},"GET",[1098,12671,5680],{"class":1332},[1098,12673,1134],{"class":1133},[1098,12675,12676],{"class":1332}," \"",[1098,12678,2643],{"class":1336},[1098,12680,5680],{"class":1332},[1098,12682,1134],{"class":1133},[1098,12684,12676],{"class":1332},[1098,12686,12687],{"class":1336},"PUT",[1098,12689,5680],{"class":1332},[1098,12691,1134],{"class":1133},[1098,12693,12676],{"class":1332},[1098,12695,8390],{"class":1336},[1098,12697,5680],{"class":1332},[1098,12699,1427],{"class":1133},[1098,12701,12702,12705,12707,12709,12711,12714,12716],{"class":1100,"line":1560},[1098,12703,12704],{"class":11716},"        paths",[1098,12706,1864],{"class":1133},[1098,12708,4538],{"class":1133},[1098,12710,5680],{"class":1332},[1098,12712,12713],{"class":1336},"/api/v1/users/*",[1098,12715,5680],{"class":1332},[1098,12717,1427],{"class":1133},[1098,12719,12720],{"class":1100,"line":1580},[1098,12721,1220],{"emptyLinePlaceholder":1219},[1098,12723,12724],{"class":1100,"line":1585},[1098,12725,12227],{"class":1258},[1098,12727,12728,12730,12732],{"class":1100,"line":1617},[1098,12729,11717],{"class":11716},[1098,12731,1864],{"class":1133},[1098,12733,12442],{"class":1336},[1098,12735,12736,12738,12740],{"class":1100,"line":1634},[1098,12737,11727],{"class":11716},[1098,12739,1864],{"class":1133},[1098,12741,12742],{"class":1336}," RequestAuthentication\n",[1098,12744,12745,12747],{"class":1100,"line":1652},[1098,12746,11737],{"class":11716},[1098,12748,1441],{"class":1133},[1098,12750,12751,12753,12755],{"class":1100,"line":1657},[1098,12752,11744],{"class":11716},[1098,12754,1864],{"class":1133},[1098,12756,12757],{"class":1336}," jwt-auth\n",[1098,12759,12760,12762,12764],{"class":1100,"line":1675},[1098,12761,11754],{"class":11716},[1098,12763,1864],{"class":1133},[1098,12765,11759],{"class":1336},[1098,12767,12768,12770],{"class":1100,"line":1680},[1098,12769,11764],{"class":11716},[1098,12771,1441],{"class":1133},[1098,12773,12774,12776],{"class":1100,"line":1695},[1098,12775,12556],{"class":11716},[1098,12777,1441],{"class":1133},[1098,12779,12780,12782],{"class":1100,"line":1714},[1098,12781,12283],{"class":11716},[1098,12783,1441],{"class":1133},[1098,12785,12786,12788,12790],{"class":1100,"line":1728},[1098,12787,12290],{"class":11716},[1098,12789,1864],{"class":1133},[1098,12791,11921],{"class":1336},[1098,12793,12794,12797],{"class":1100,"line":1746},[1098,12795,12796],{"class":11716},"  jwtRules",[1098,12798,1441],{"class":1133},[1098,12800,12801,12803,12806,12808,12810,12813],{"class":1100,"line":1760},[1098,12802,11787],{"class":1133},[1098,12804,12805],{"class":11716}," issuer",[1098,12807,1864],{"class":1133},[1098,12809,12676],{"class":1332},[1098,12811,12812],{"class":1336},"https://auth.example.com",[1098,12814,5705],{"class":1332},[1098,12816,12817,12820,12822,12824,12827],{"class":1100,"line":1778},[1098,12818,12819],{"class":11716},"    jwksUri",[1098,12821,1864],{"class":1133},[1098,12823,12676],{"class":1332},[1098,12825,12826],{"class":1336},"https://auth.example.com/.well-known/jwks.json",[1098,12828,5705],{"class":1332},[1098,12830,12831,12834],{"class":1100,"line":1783},[1098,12832,12833],{"class":11716},"    audiences",[1098,12835,1441],{"class":1133},[1098,12837,12838,12840,12842,12845],{"class":1100,"line":1793},[1098,12839,11828],{"class":1133},[1098,12841,12676],{"class":1332},[1098,12843,12844],{"class":1336},"microservices-api",[1098,12846,5705],{"class":1332},[1030,12848,12850],{"id":12849},"security-monitoring","Security Monitoring",[1035,12852,12854],{"id":12853},"_1-security-logging","1. Security Logging",[1088,12856,12858],{"className":1090,"code":12857,"language":1092,"meta":1093,"style":1093},"# security_logging.py\nimport logging\nimport json\nfrom django.utils.deprecation import MiddlewareMixin\nfrom django.http import HttpResponseForbidden\nimport time\n\nsecurity_logger = logging.getLogger('security')\n\nclass SecurityLoggingMiddleware(MiddlewareMixin):\n    \"\"\"Log security events\"\"\"\n    \n    def __init__(self, get_response):\n        self.get_response = get_response\n        self.suspicious_patterns = [\n            r'\u003Cscript[^>]*>.*?\u003C/script>',\n            r'javascript:',\n            r'(\\b(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\\b)',\n            r'(--|#|/\\*|\\*/)',\n        ]\n    \n    def __call__(self, request):\n        start_time = time.time()\n        \n        # Check for suspicious patterns\n        if self.detect_suspicious_activity(request):\n            self.log_security_event(request, 'SUSPICIOUS_REQUEST', {\n                'user_agent': request.META.get('HTTP_USER_AGENT'),\n                'ip_address': self.get_client_ip(request),\n                'path': request.path,\n                'method': request.method\n            })\n            \n            return HttpResponseForbidden('Suspicious activity detected')\n        \n        response = self.get_response(request)\n        \n        # Log authentication failures\n        if response.status_code == 401:\n            self.log_security_event(request, 'AUTH_FAILURE', {\n                'path': request.path,\n                'method': request.method,\n                'ip_address': self.get_client_ip(request)\n            })\n        \n        # Log access to sensitive endpoints\n        if self.is_sensitive_endpoint(request.path):\n            self.log_security_event(request, 'SENSITIVE_ACCESS', {\n                'user': str(request.user) if request.user.is_authenticated else 'anonymous',\n                'path': request.path,\n                'method': request.method,\n                'ip_address': self.get_client_ip(request),\n                'response_time': time.time() - start_time\n            })\n        \n        return response\n    \n    def detect_suspicious_activity(self, request):\n        \"\"\"Detect suspicious request patterns\"\"\"\n        # Check query parameters\n        for key, value in request.GET.items():\n            if self.contains_suspicious_pattern(value):\n                return True\n        \n        # Check POST data\n        if hasattr(request, 'body') and request.body:\n            try:\n                body_str = request.body.decode('utf-8')\n                if self.contains_suspicious_pattern(body_str):\n                    return True\n            except UnicodeDecodeError:\n                pass\n        \n        return False\n    \n    def contains_suspicious_pattern(self, text):\n        \"\"\"Check if text contains suspicious patterns\"\"\"\n        import re\n        \n        for pattern in self.suspicious_patterns:\n            if re.search(pattern, text, re.IGNORECASE):\n                return True\n        \n        return False\n    \n    def is_sensitive_endpoint(self, path):\n        \"\"\"Check if endpoint is sensitive\"\"\"\n        sensitive_patterns = [\n            r'/admin/',\n            r'/api/.*/users/',\n            r'/api/.*/auth/',\n            r'/api/.*/payments/',\n        ]\n        \n        import re\n        for pattern in sensitive_patterns:\n            if re.search(pattern, path):\n                return True\n        \n        return False\n    \n    def get_client_ip(self, request):\n        \"\"\"Get client IP address\"\"\"\n        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')\n        if x_forwarded_for:\n            ip = x_forwarded_for.split(',')[0]\n        else:\n            ip = request.META.get('REMOTE_ADDR')\n        return ip\n    \n    def log_security_event(self, request, event_type, details):\n        \"\"\"Log security event\"\"\"\n        event_data = {\n            'timestamp': time.time(),\n            'event_type': event_type,\n            'service': 'user-service',\n            'details': details\n        }\n        \n        security_logger.warning(json.dumps(event_data))\n\n# Intrusion detection\nclass IntrusionDetectionSystem:\n    \"\"\"Simple intrusion detection system\"\"\"\n    \n    def __init__(self):\n        self.failed_attempts = {}\n        self.blocked_ips = set()\n    \n    def record_failed_attempt(self, ip_address):\n        \"\"\"Record failed authentication attempt\"\"\"\n        if ip_address not in self.failed_attempts:\n            self.failed_attempts[ip_address] = []\n        \n        self.failed_attempts[ip_address].append(time.time())\n        \n        # Remove old attempts (older than 1 hour)\n        cutoff_time = time.time() - 3600\n        self.failed_attempts[ip_address] = [\n            attempt for attempt in self.failed_attempts[ip_address]\n            if attempt > cutoff_time\n        ]\n        \n        # Block IP if too many failed attempts\n        if len(self.failed_attempts[ip_address]) >= 5:\n            self.blocked_ips.add(ip_address)\n            \n            security_logger.critical(json.dumps({\n                'event_type': 'IP_BLOCKED',\n                'ip_address': ip_address,\n                'failed_attempts': len(self.failed_attempts[ip_address]),\n                'timestamp': time.time()\n            }))\n    \n    def is_blocked(self, ip_address):\n        \"\"\"Check if IP is blocked\"\"\"\n        return ip_address in self.blocked_ips\n    \n    def unblock_ip(self, ip_address):\n        \"\"\"Unblock IP address\"\"\"\n        self.blocked_ips.discard(ip_address)\n        if ip_address in self.failed_attempts:\n            del self.failed_attempts[ip_address]\n\nids = IntrusionDetectionSystem()\n",[1095,12859,12860,12865,12872,12878,12899,12915,12921,12925,12951,12955,12969,12978,12982,12998,13010,13023,13053,13065,13113,13145,13149,13153,13169,13184,13188,13193,13210,13236,13268,13292,13311,13328,13333,13337,13354,13358,13376,13380,13385,13402,13427,13445,13463,13485,13489,13493,13498,13519,13544,13591,13609,13627,13649,13673,13677,13681,13687,13691,13708,13717,13722,13746,13763,13769,13773,13778,13809,13815,13843,13861,13868,13877,13882,13886,13892,13896,13914,13923,13929,13933,13949,13977,13983,13987,13993,13997,14015,14024,14033,14046,14066,14085,14104,14108,14112,14118,14131,14151,14157,14161,14167,14171,14188,14197,14225,14234,14262,14268,14295,14302,14306,14333,14342,14351,14369,14384,14404,14418,14422,14426,14451,14455,14460,14469,14478,14482,14494,14507,14522,14526,14544,14553,14573,14591,14595,14623,14627,14632,14652,14670,14695,14706,14710,14714,14719,14747,14766,14770,14790,14809,14823,14850,14868,14873,14877,14894,14903,14918,14922,14939,14948,14967,14983,15000,15004],{"__ignoreMap":1093},[1098,12861,12862],{"class":1100,"line":1101},[1098,12863,12864],{"class":1104},"# security_logging.py\n",[1098,12866,12867,12869],{"class":1100,"line":1108},[1098,12868,1112],{"class":1111},[1098,12870,12871],{"class":1115}," logging\n",[1098,12873,12874,12876],{"class":1100,"line":1119},[1098,12875,1112],{"class":1111},[1098,12877,10607],{"class":1115},[1098,12879,12880,12882,12884,12886,12889,12891,12894,12896],{"class":1100,"line":1140},[1098,12881,1122],{"class":1111},[1098,12883,1145],{"class":1115},[1098,12885,1148],{"class":1133},[1098,12887,12888],{"class":1115},"utils",[1098,12890,1148],{"class":1133},[1098,12892,12893],{"class":1115},"deprecation ",[1098,12895,1112],{"class":1111},[1098,12897,12898],{"class":1115}," MiddlewareMixin\n",[1098,12900,12901,12903,12905,12907,12910,12912],{"class":1100,"line":1159},[1098,12902,1122],{"class":1111},[1098,12904,1145],{"class":1115},[1098,12906,1148],{"class":1133},[1098,12908,12909],{"class":1115},"http ",[1098,12911,1112],{"class":1111},[1098,12913,12914],{"class":1115}," HttpResponseForbidden\n",[1098,12916,12917,12919],{"class":1100,"line":1181},[1098,12918,1112],{"class":1111},[1098,12920,5071],{"class":1115},[1098,12922,12923],{"class":1100,"line":1199},[1098,12924,1220],{"emptyLinePlaceholder":1219},[1098,12926,12927,12930,12932,12935,12937,12940,12942,12944,12947,12949],{"class":1100,"line":1216},[1098,12928,12929],{"class":1115},"security_logger ",[1098,12931,1229],{"class":1133},[1098,12933,12934],{"class":1115}," logging",[1098,12936,1148],{"class":1133},[1098,12938,12939],{"class":1232},"getLogger",[1098,12941,1255],{"class":1133},[1098,12943,1333],{"class":1332},[1098,12945,12946],{"class":1336},"security",[1098,12948,1333],{"class":1332},[1098,12950,1342],{"class":1133},[1098,12952,12953],{"class":1100,"line":1223},[1098,12954,1220],{"emptyLinePlaceholder":1219},[1098,12956,12957,12959,12962,12964,12967],{"class":1100,"line":1239},[1098,12958,1248],{"class":1247},[1098,12960,12961],{"class":1251}," SecurityLoggingMiddleware",[1098,12963,1255],{"class":1133},[1098,12965,12966],{"class":1258},"MiddlewareMixin",[1098,12968,1262],{"class":1133},[1098,12970,12971,12973,12976],{"class":1100,"line":1244},[1098,12972,1269],{"class":1268},[1098,12974,12975],{"class":1272},"Log security events",[1098,12977,1276],{"class":1268},[1098,12979,12980],{"class":1100,"line":1265},[1098,12981,1282],{"class":1115},[1098,12983,12984,12986,12988,12990,12992,12994,12996],{"class":1100,"line":1279},[1098,12985,1288],{"class":1247},[1098,12987,5800],{"class":4766},[1098,12989,1255],{"class":1133},[1098,12991,1298],{"class":1297},[1098,12993,1134],{"class":1133},[1098,12995,6823],{"class":1303},[1098,12997,1262],{"class":1133},[1098,12999,13000,13002,13004,13006,13008],{"class":1100,"line":1285},[1098,13001,5815],{"class":3697},[1098,13003,1148],{"class":1133},[1098,13005,6834],{"class":1598},[1098,13007,5822],{"class":1133},[1098,13009,6839],{"class":1115},[1098,13011,13012,13014,13016,13019,13021],{"class":1100,"line":1309},[1098,13013,5815],{"class":3697},[1098,13015,1148],{"class":1133},[1098,13017,13018],{"class":1598},"suspicious_patterns",[1098,13020,5822],{"class":1133},[1098,13022,8355],{"class":1133},[1098,13024,13025,13027,13029,13031,13033,13035,13037,13039,13041,13043,13045,13047,13049,13051],{"class":1100,"line":1345},[1098,13026,8360],{"class":1247},[1098,13028,1333],{"class":1332},[1098,13030,8721],{"class":8373},[1098,13032,3327],{"class":8724},[1098,13034,8727],{"class":1351},[1098,13036,8731],{"class":8730},[1098,13038,6168],{"class":8724},[1098,13040,8449],{"class":8448},[1098,13042,8731],{"class":8373},[1098,13044,1148],{"class":8367},[1098,13046,8742],{"class":8448},[1098,13048,8745],{"class":8373},[1098,13050,1333],{"class":1332},[1098,13052,1873],{"class":1133},[1098,13054,13055,13057,13059,13061,13063],{"class":1100,"line":1382},[1098,13056,8360],{"class":1247},[1098,13058,1333],{"class":1332},[1098,13060,8758],{"class":8373},[1098,13062,1333],{"class":1332},[1098,13064,1873],{"class":1133},[1098,13066,13067,13069,13071,13073,13075,13077,13079,13081,13083,13085,13087,13089,13091,13093,13095,13097,13099,13101,13103,13105,13107,13109,13111],{"class":1100,"line":1392},[1098,13068,8360],{"class":1247},[1098,13070,1333],{"class":1332},[1098,13072,1255],{"class":1133},[1098,13074,8368],{"class":8367},[1098,13076,1255],{"class":1133},[1098,13078,8374],{"class":8373},[1098,13080,8377],{"class":1351},[1098,13082,8380],{"class":8373},[1098,13084,8377],{"class":1351},[1098,13086,8385],{"class":8373},[1098,13088,8377],{"class":1351},[1098,13090,8390],{"class":8373},[1098,13092,8377],{"class":1351},[1098,13094,8395],{"class":8373},[1098,13096,8377],{"class":1351},[1098,13098,8400],{"class":8373},[1098,13100,8377],{"class":1351},[1098,13102,8405],{"class":8373},[1098,13104,2414],{"class":1133},[1098,13106,8368],{"class":8367},[1098,13108,2414],{"class":1133},[1098,13110,1333],{"class":1332},[1098,13112,1873],{"class":1133},[1098,13114,13115,13117,13119,13121,13123,13125,13127,13129,13131,13133,13135,13137,13139,13141,13143],{"class":1100,"line":1398},[1098,13116,8360],{"class":1247},[1098,13118,1333],{"class":1332},[1098,13120,1255],{"class":1133},[1098,13122,8488],{"class":8373},[1098,13124,8377],{"class":1351},[1098,13126,8493],{"class":8373},[1098,13128,8377],{"class":1351},[1098,13130,8498],{"class":8373},[1098,13132,8502],{"class":8501},[1098,13134,8377],{"class":1351},[1098,13136,8502],{"class":8501},[1098,13138,8498],{"class":8373},[1098,13140,2414],{"class":1133},[1098,13142,1333],{"class":1332},[1098,13144,1873],{"class":1133},[1098,13146,13147],{"class":1100,"line":1430},[1098,13148,8549],{"class":1133},[1098,13150,13151],{"class":1100,"line":1435},[1098,13152,1282],{"class":1115},[1098,13154,13155,13157,13159,13161,13163,13165,13167],{"class":1100,"line":1444},[1098,13156,1288],{"class":1247},[1098,13158,6850],{"class":4766},[1098,13160,1255],{"class":1133},[1098,13162,1298],{"class":1297},[1098,13164,1134],{"class":1133},[1098,13166,1304],{"class":1303},[1098,13168,1262],{"class":1133},[1098,13170,13171,13174,13176,13178,13180,13182],{"class":1100,"line":1463},[1098,13172,13173],{"class":1115},"        start_time ",[1098,13175,1229],{"class":1133},[1098,13177,5355],{"class":1115},[1098,13179,1148],{"class":1133},[1098,13181,5360],{"class":1232},[1098,13183,1236],{"class":1133},[1098,13185,13186],{"class":1100,"line":1474},[1098,13187,1395],{"class":1115},[1098,13189,13190],{"class":1100,"line":1489},[1098,13191,13192],{"class":1104},"        # Check for suspicious patterns\n",[1098,13194,13195,13197,13199,13201,13204,13206,13208],{"class":1100,"line":1509},[1098,13196,1348],{"class":1111},[1098,13198,3698],{"class":3697},[1098,13200,1148],{"class":1133},[1098,13202,13203],{"class":1232},"detect_suspicious_activity",[1098,13205,1255],{"class":1133},[1098,13207,2677],{"class":1232},[1098,13209,1262],{"class":1133},[1098,13211,13212,13214,13216,13219,13221,13223,13225,13227,13230,13232,13234],{"class":1100,"line":1515},[1098,13213,7381],{"class":3697},[1098,13215,1148],{"class":1133},[1098,13217,13218],{"class":1232},"log_security_event",[1098,13220,1255],{"class":1133},[1098,13222,2677],{"class":1232},[1098,13224,1134],{"class":1133},[1098,13226,1417],{"class":1332},[1098,13228,13229],{"class":1336},"SUSPICIOUS_REQUEST",[1098,13231,1333],{"class":1332},[1098,13233,1134],{"class":1133},[1098,13235,1851],{"class":1133},[1098,13237,13238,13240,13243,13245,13247,13249,13251,13253,13255,13257,13259,13261,13264,13266],{"class":1100,"line":1521},[1098,13239,4103],{"class":1332},[1098,13241,13242],{"class":1336},"user_agent",[1098,13244,1333],{"class":1332},[1098,13246,1864],{"class":1133},[1098,13248,1304],{"class":1232},[1098,13250,1148],{"class":1133},[1098,13252,1322],{"class":1321},[1098,13254,1148],{"class":1133},[1098,13256,1327],{"class":1232},[1098,13258,1255],{"class":1133},[1098,13260,1333],{"class":1332},[1098,13262,13263],{"class":1336},"HTTP_USER_AGENT",[1098,13265,1333],{"class":1332},[1098,13267,1958],{"class":1133},[1098,13269,13270,13272,13275,13277,13279,13281,13283,13286,13288,13290],{"class":1100,"line":1547},[1098,13271,4103],{"class":1332},[1098,13273,13274],{"class":1336},"ip_address",[1098,13276,1333],{"class":1332},[1098,13278,1864],{"class":1133},[1098,13280,3698],{"class":3697},[1098,13282,1148],{"class":1133},[1098,13284,13285],{"class":1232},"get_client_ip",[1098,13287,1255],{"class":1133},[1098,13289,2677],{"class":1232},[1098,13291,1958],{"class":1133},[1098,13293,13294,13296,13299,13301,13303,13305,13307,13309],{"class":1100,"line":1560},[1098,13295,4103],{"class":1332},[1098,13297,13298],{"class":1336},"path",[1098,13300,1333],{"class":1332},[1098,13302,1864],{"class":1133},[1098,13304,1304],{"class":1232},[1098,13306,1148],{"class":1133},[1098,13308,13298],{"class":1598},[1098,13310,1873],{"class":1133},[1098,13312,13313,13315,13317,13319,13321,13323,13325],{"class":1100,"line":1580},[1098,13314,4103],{"class":1332},[1098,13316,6192],{"class":1336},[1098,13318,1333],{"class":1332},[1098,13320,1864],{"class":1133},[1098,13322,1304],{"class":1232},[1098,13324,1148],{"class":1133},[1098,13326,13327],{"class":1598},"method\n",[1098,13329,13330],{"class":1100,"line":1585},[1098,13331,13332],{"class":1133},"            })\n",[1098,13334,13335],{"class":1100,"line":1617},[1098,13336,1518],{"class":1115},[1098,13338,13339,13341,13343,13345,13347,13350,13352],{"class":1100,"line":1634},[1098,13340,1385],{"class":1111},[1098,13342,6891],{"class":1232},[1098,13344,1255],{"class":1133},[1098,13346,1333],{"class":1332},[1098,13348,13349],{"class":1336},"Suspicious activity detected",[1098,13351,1333],{"class":1332},[1098,13353,1342],{"class":1133},[1098,13355,13356],{"class":1100,"line":1652},[1098,13357,1395],{"class":1115},[1098,13359,13360,13362,13364,13366,13368,13370,13372,13374],{"class":1100,"line":1657},[1098,13361,6911],{"class":1115},[1098,13363,1229],{"class":1133},[1098,13365,3698],{"class":3697},[1098,13367,1148],{"class":1133},[1098,13369,6834],{"class":1232},[1098,13371,1255],{"class":1133},[1098,13373,2677],{"class":1232},[1098,13375,1342],{"class":1133},[1098,13377,13378],{"class":1100,"line":1675},[1098,13379,1395],{"class":1115},[1098,13381,13382],{"class":1100,"line":1680},[1098,13383,13384],{"class":1104},"        # Log authentication failures\n",[1098,13386,13387,13389,13391,13393,13395,13397,13400],{"class":1100,"line":1695},[1098,13388,1348],{"class":1111},[1098,13390,3909],{"class":1115},[1098,13392,1148],{"class":1133},[1098,13394,3914],{"class":1598},[1098,13396,3917],{"class":1351},[1098,13398,13399],{"class":1423}," 401",[1098,13401,1441],{"class":1133},[1098,13403,13404,13406,13408,13410,13412,13414,13416,13418,13421,13423,13425],{"class":1100,"line":1714},[1098,13405,7381],{"class":3697},[1098,13407,1148],{"class":1133},[1098,13409,13218],{"class":1232},[1098,13411,1255],{"class":1133},[1098,13413,2677],{"class":1232},[1098,13415,1134],{"class":1133},[1098,13417,1417],{"class":1332},[1098,13419,13420],{"class":1336},"AUTH_FAILURE",[1098,13422,1333],{"class":1332},[1098,13424,1134],{"class":1133},[1098,13426,1851],{"class":1133},[1098,13428,13429,13431,13433,13435,13437,13439,13441,13443],{"class":1100,"line":1728},[1098,13430,4103],{"class":1332},[1098,13432,13298],{"class":1336},[1098,13434,1333],{"class":1332},[1098,13436,1864],{"class":1133},[1098,13438,1304],{"class":1232},[1098,13440,1148],{"class":1133},[1098,13442,13298],{"class":1598},[1098,13444,1873],{"class":1133},[1098,13446,13447,13449,13451,13453,13455,13457,13459,13461],{"class":1100,"line":1746},[1098,13448,4103],{"class":1332},[1098,13450,6192],{"class":1336},[1098,13452,1333],{"class":1332},[1098,13454,1864],{"class":1133},[1098,13456,1304],{"class":1232},[1098,13458,1148],{"class":1133},[1098,13460,6192],{"class":1598},[1098,13462,1873],{"class":1133},[1098,13464,13465,13467,13469,13471,13473,13475,13477,13479,13481,13483],{"class":1100,"line":1760},[1098,13466,4103],{"class":1332},[1098,13468,13274],{"class":1336},[1098,13470,1333],{"class":1332},[1098,13472,1864],{"class":1133},[1098,13474,3698],{"class":3697},[1098,13476,1148],{"class":1133},[1098,13478,13285],{"class":1232},[1098,13480,1255],{"class":1133},[1098,13482,2677],{"class":1232},[1098,13484,1342],{"class":1133},[1098,13486,13487],{"class":1100,"line":1778},[1098,13488,13332],{"class":1133},[1098,13490,13491],{"class":1100,"line":1783},[1098,13492,1395],{"class":1115},[1098,13494,13495],{"class":1100,"line":1793},[1098,13496,13497],{"class":1104},"        # Log access to sensitive endpoints\n",[1098,13499,13500,13502,13504,13506,13509,13511,13513,13515,13517],{"class":1100,"line":1803},[1098,13501,1348],{"class":1111},[1098,13503,3698],{"class":3697},[1098,13505,1148],{"class":1133},[1098,13507,13508],{"class":1232},"is_sensitive_endpoint",[1098,13510,1255],{"class":1133},[1098,13512,2677],{"class":1232},[1098,13514,1148],{"class":1133},[1098,13516,13298],{"class":1598},[1098,13518,1262],{"class":1133},[1098,13520,13521,13523,13525,13527,13529,13531,13533,13535,13538,13540,13542],{"class":1100,"line":1808},[1098,13522,7381],{"class":3697},[1098,13524,1148],{"class":1133},[1098,13526,13218],{"class":1232},[1098,13528,1255],{"class":1133},[1098,13530,2677],{"class":1232},[1098,13532,1134],{"class":1133},[1098,13534,1417],{"class":1332},[1098,13536,13537],{"class":1336},"SENSITIVE_ACCESS",[1098,13539,1333],{"class":1332},[1098,13541,1134],{"class":1133},[1098,13543,1851],{"class":1133},[1098,13545,13546,13548,13550,13552,13554,13556,13558,13560,13562,13564,13566,13569,13571,13573,13575,13577,13579,13582,13584,13587,13589],{"class":1100,"line":1818},[1098,13547,4103],{"class":1332},[1098,13549,1665],{"class":1336},[1098,13551,1333],{"class":1332},[1098,13553,1864],{"class":1133},[1098,13555,3453],{"class":1814},[1098,13557,1255],{"class":1133},[1098,13559,2677],{"class":1232},[1098,13561,1148],{"class":1133},[1098,13563,1665],{"class":1598},[1098,13565,2414],{"class":1133},[1098,13567,13568],{"class":1111}," if",[1098,13570,1304],{"class":1232},[1098,13572,1148],{"class":1133},[1098,13574,1665],{"class":1598},[1098,13576,1148],{"class":1133},[1098,13578,4377],{"class":1598},[1098,13580,13581],{"class":1111}," else",[1098,13583,1417],{"class":1332},[1098,13585,13586],{"class":1336},"anonymous",[1098,13588,1333],{"class":1332},[1098,13590,1873],{"class":1133},[1098,13592,13593,13595,13597,13599,13601,13603,13605,13607],{"class":1100,"line":1832},[1098,13594,4103],{"class":1332},[1098,13596,13298],{"class":1336},[1098,13598,1333],{"class":1332},[1098,13600,1864],{"class":1133},[1098,13602,1304],{"class":1232},[1098,13604,1148],{"class":1133},[1098,13606,13298],{"class":1598},[1098,13608,1873],{"class":1133},[1098,13610,13611,13613,13615,13617,13619,13621,13623,13625],{"class":1100,"line":1843},[1098,13612,4103],{"class":1332},[1098,13614,6192],{"class":1336},[1098,13616,1333],{"class":1332},[1098,13618,1864],{"class":1133},[1098,13620,1304],{"class":1232},[1098,13622,1148],{"class":1133},[1098,13624,6192],{"class":1598},[1098,13626,1873],{"class":1133},[1098,13628,13629,13631,13633,13635,13637,13639,13641,13643,13645,13647],{"class":1100,"line":1854},[1098,13630,4103],{"class":1332},[1098,13632,13274],{"class":1336},[1098,13634,1333],{"class":1332},[1098,13636,1864],{"class":1133},[1098,13638,3698],{"class":3697},[1098,13640,1148],{"class":1133},[1098,13642,13285],{"class":1232},[1098,13644,1255],{"class":1133},[1098,13646,2677],{"class":1232},[1098,13648,1958],{"class":1133},[1098,13650,13651,13653,13656,13658,13660,13662,13664,13666,13668,13670],{"class":1100,"line":1876},[1098,13652,4103],{"class":1332},[1098,13654,13655],{"class":1336},"response_time",[1098,13657,1333],{"class":1332},[1098,13659,1864],{"class":1133},[1098,13661,5355],{"class":1232},[1098,13663,1148],{"class":1133},[1098,13665,5360],{"class":1232},[1098,13667,1935],{"class":1133},[1098,13669,7367],{"class":1351},[1098,13671,13672],{"class":1232}," start_time\n",[1098,13674,13675],{"class":1100,"line":1896},[1098,13676,13332],{"class":1133},[1098,13678,13679],{"class":1100,"line":1916},[1098,13680,1395],{"class":1115},[1098,13682,13683,13685],{"class":1100,"line":1961},[1098,13684,2016],{"class":1111},[1098,13686,6932],{"class":1115},[1098,13688,13689],{"class":1100,"line":1982},[1098,13690,1282],{"class":1115},[1098,13692,13693,13695,13698,13700,13702,13704,13706],{"class":1100,"line":2002},[1098,13694,1288],{"class":1247},[1098,13696,13697],{"class":1291}," detect_suspicious_activity",[1098,13699,1255],{"class":1133},[1098,13701,1298],{"class":1297},[1098,13703,1134],{"class":1133},[1098,13705,1304],{"class":1303},[1098,13707,1262],{"class":1133},[1098,13709,13710,13712,13715],{"class":1100,"line":2008},[1098,13711,1835],{"class":1268},[1098,13713,13714],{"class":1272},"Detect suspicious request patterns",[1098,13716,1276],{"class":1268},[1098,13718,13719],{"class":1100,"line":2013},[1098,13720,13721],{"class":1104},"        # Check query parameters\n",[1098,13723,13724,13726,13728,13730,13732,13734,13736,13738,13740,13742,13744],{"class":1100,"line":2028},[1098,13725,8020],{"class":1111},[1098,13727,11406],{"class":1115},[1098,13729,1134],{"class":1133},[1098,13731,8028],{"class":1115},[1098,13733,5027],{"class":1111},[1098,13735,1304],{"class":1115},[1098,13737,1148],{"class":1133},[1098,13739,12669],{"class":1321},[1098,13741,1148],{"class":1133},[1098,13743,8037],{"class":1232},[1098,13745,4744],{"class":1133},[1098,13747,13748,13750,13752,13754,13757,13759,13761],{"class":1100,"line":2038},[1098,13749,1550],{"class":1111},[1098,13751,3698],{"class":3697},[1098,13753,1148],{"class":1133},[1098,13755,13756],{"class":1232},"contains_suspicious_pattern",[1098,13758,1255],{"class":1133},[1098,13760,8051],{"class":1232},[1098,13762,1262],{"class":1133},[1098,13764,13765,13767],{"class":1100,"line":2052},[1098,13766,3927],{"class":1111},[1098,13768,4208],{"class":1388},[1098,13770,13771],{"class":1100,"line":2067},[1098,13772,1395],{"class":1115},[1098,13774,13775],{"class":1100,"line":2073},[1098,13776,13777],{"class":1104},"        # Check POST data\n",[1098,13779,13780,13782,13784,13786,13788,13790,13792,13795,13797,13799,13801,13803,13805,13807],{"class":1100,"line":2078},[1098,13781,1348],{"class":1111},[1098,13783,4767],{"class":4766},[1098,13785,1255],{"class":1133},[1098,13787,2677],{"class":1232},[1098,13789,1134],{"class":1133},[1098,13791,1417],{"class":1332},[1098,13793,13794],{"class":1336},"body",[1098,13796,1333],{"class":1332},[1098,13798,2414],{"class":1133},[1098,13800,7341],{"class":1351},[1098,13802,1304],{"class":1115},[1098,13804,1148],{"class":1133},[1098,13806,13794],{"class":1598},[1098,13808,1441],{"class":1133},[1098,13810,13811,13813],{"class":1100,"line":2085},[1098,13812,10831],{"class":1111},[1098,13814,1441],{"class":1133},[1098,13816,13817,13820,13822,13824,13826,13828,13830,13832,13834,13836,13839,13841],{"class":1100,"line":2099},[1098,13818,13819],{"class":1115},"                body_str ",[1098,13821,1229],{"class":1133},[1098,13823,1304],{"class":1115},[1098,13825,1148],{"class":1133},[1098,13827,13794],{"class":1598},[1098,13829,1148],{"class":1133},[1098,13831,1457],{"class":1232},[1098,13833,1255],{"class":1133},[1098,13835,1333],{"class":1332},[1098,13837,13838],{"class":1336},"utf-8",[1098,13840,1333],{"class":1332},[1098,13842,1342],{"class":1133},[1098,13844,13845,13848,13850,13852,13854,13856,13859],{"class":1100,"line":2109},[1098,13846,13847],{"class":1111},"                if",[1098,13849,3698],{"class":3697},[1098,13851,1148],{"class":1133},[1098,13853,13756],{"class":1232},[1098,13855,1255],{"class":1133},[1098,13857,13858],{"class":1232},"body_str",[1098,13860,1262],{"class":1133},[1098,13862,13863,13866],{"class":1100,"line":2118},[1098,13864,13865],{"class":1111},"                    return",[1098,13867,4208],{"class":1388},[1098,13869,13870,13872,13875],{"class":1100,"line":2137},[1098,13871,10929],{"class":1111},[1098,13873,13874],{"class":1814}," UnicodeDecodeError",[1098,13876,1441],{"class":1133},[1098,13878,13879],{"class":1100,"line":2176},[1098,13880,13881],{"class":1111},"                pass\n",[1098,13883,13884],{"class":1100,"line":2195},[1098,13885,1395],{"class":1115},[1098,13887,13888,13890],{"class":1100,"line":2213},[1098,13889,2016],{"class":1111},[1098,13891,4386],{"class":1388},[1098,13893,13894],{"class":1100,"line":2218},[1098,13895,1282],{"class":1115},[1098,13897,13898,13900,13903,13905,13907,13909,13912],{"class":1100,"line":2223},[1098,13899,1288],{"class":1247},[1098,13901,13902],{"class":1291}," contains_suspicious_pattern",[1098,13904,1255],{"class":1133},[1098,13906,1298],{"class":1297},[1098,13908,1134],{"class":1133},[1098,13910,13911],{"class":1303}," text",[1098,13913,1262],{"class":1133},[1098,13915,13916,13918,13921],{"class":1100,"line":2236},[1098,13917,1835],{"class":1268},[1098,13919,13920],{"class":1272},"Check if text contains suspicious patterns",[1098,13922,1276],{"class":1268},[1098,13924,13925,13927],{"class":1100,"line":2245},[1098,13926,11574],{"class":1111},[1098,13928,7947],{"class":1115},[1098,13930,13931],{"class":1100,"line":2258},[1098,13932,1395],{"class":1115},[1098,13934,13935,13937,13939,13941,13943,13945,13947],{"class":1100,"line":2271},[1098,13936,8020],{"class":1111},[1098,13938,8597],{"class":1115},[1098,13940,5027],{"class":1111},[1098,13942,3698],{"class":3697},[1098,13944,1148],{"class":1133},[1098,13946,13018],{"class":1598},[1098,13948,1441],{"class":1133},[1098,13950,13951,13953,13955,13957,13959,13961,13963,13965,13967,13969,13971,13973,13975],{"class":1100,"line":2276},[1098,13952,1550],{"class":1111},[1098,13954,8612],{"class":1115},[1098,13956,1148],{"class":1133},[1098,13958,8617],{"class":1232},[1098,13960,1255],{"class":1133},[1098,13962,8622],{"class":1232},[1098,13964,1134],{"class":1133},[1098,13966,13911],{"class":1232},[1098,13968,1134],{"class":1133},[1098,13970,8612],{"class":1232},[1098,13972,1148],{"class":1133},[1098,13974,8635],{"class":1321},[1098,13976,1262],{"class":1133},[1098,13978,13979,13981],{"class":1100,"line":2281},[1098,13980,3927],{"class":1111},[1098,13982,4208],{"class":1388},[1098,13984,13985],{"class":1100,"line":2288},[1098,13986,1395],{"class":1115},[1098,13988,13989,13991],{"class":1100,"line":2316},[1098,13990,2016],{"class":1111},[1098,13992,4386],{"class":1388},[1098,13994,13995],{"class":1100,"line":2326},[1098,13996,1282],{"class":1115},[1098,13998,13999,14001,14004,14006,14008,14010,14013],{"class":1100,"line":2333},[1098,14000,1288],{"class":1247},[1098,14002,14003],{"class":1291}," is_sensitive_endpoint",[1098,14005,1255],{"class":1133},[1098,14007,1298],{"class":1297},[1098,14009,1134],{"class":1133},[1098,14011,14012],{"class":1303}," path",[1098,14014,1262],{"class":1133},[1098,14016,14017,14019,14022],{"class":1100,"line":2348},[1098,14018,1835],{"class":1268},[1098,14020,14021],{"class":1272},"Check if endpoint is sensitive",[1098,14023,1276],{"class":1268},[1098,14025,14026,14029,14031],{"class":1100,"line":2357},[1098,14027,14028],{"class":1115},"        sensitive_patterns ",[1098,14030,1229],{"class":1133},[1098,14032,8355],{"class":1133},[1098,14034,14035,14037,14039,14042,14044],{"class":1100,"line":2370},[1098,14036,8360],{"class":1247},[1098,14038,1333],{"class":1332},[1098,14040,14041],{"class":8373},"/admin/",[1098,14043,1333],{"class":1332},[1098,14045,1873],{"class":1133},[1098,14047,14048,14050,14052,14055,14057,14059,14062,14064],{"class":1100,"line":2385},[1098,14049,8360],{"class":1247},[1098,14051,1333],{"class":1332},[1098,14053,14054],{"class":8373},"/api/",[1098,14056,1148],{"class":8367},[1098,14058,8449],{"class":8448},[1098,14060,14061],{"class":8373},"/users/",[1098,14063,1333],{"class":1332},[1098,14065,1873],{"class":1133},[1098,14067,14068,14070,14072,14074,14076,14078,14081,14083],{"class":1100,"line":2390},[1098,14069,8360],{"class":1247},[1098,14071,1333],{"class":1332},[1098,14073,14054],{"class":8373},[1098,14075,1148],{"class":8367},[1098,14077,8449],{"class":8448},[1098,14079,14080],{"class":8373},"/auth/",[1098,14082,1333],{"class":1332},[1098,14084,1873],{"class":1133},[1098,14086,14087,14089,14091,14093,14095,14097,14100,14102],{"class":1100,"line":2395},[1098,14088,8360],{"class":1247},[1098,14090,1333],{"class":1332},[1098,14092,14054],{"class":8373},[1098,14094,1148],{"class":8367},[1098,14096,8449],{"class":8448},[1098,14098,14099],{"class":8373},"/payments/",[1098,14101,1333],{"class":1332},[1098,14103,1873],{"class":1133},[1098,14105,14106],{"class":1100,"line":2424},[1098,14107,8549],{"class":1133},[1098,14109,14110],{"class":1100,"line":2446},[1098,14111,1395],{"class":1115},[1098,14113,14114,14116],{"class":1100,"line":2451},[1098,14115,11574],{"class":1111},[1098,14117,7947],{"class":1115},[1098,14119,14120,14122,14124,14126,14129],{"class":1100,"line":2459},[1098,14121,8020],{"class":1111},[1098,14123,8597],{"class":1115},[1098,14125,5027],{"class":1111},[1098,14127,14128],{"class":1115}," sensitive_patterns",[1098,14130,1441],{"class":1133},[1098,14132,14133,14135,14137,14139,14141,14143,14145,14147,14149],{"class":1100,"line":2464},[1098,14134,1550],{"class":1111},[1098,14136,8612],{"class":1115},[1098,14138,1148],{"class":1133},[1098,14140,8617],{"class":1232},[1098,14142,1255],{"class":1133},[1098,14144,8622],{"class":1232},[1098,14146,1134],{"class":1133},[1098,14148,14012],{"class":1232},[1098,14150,1262],{"class":1133},[1098,14152,14153,14155],{"class":1100,"line":2477},[1098,14154,3927],{"class":1111},[1098,14156,4208],{"class":1388},[1098,14158,14159],{"class":1100,"line":2494},[1098,14160,1395],{"class":1115},[1098,14162,14163,14165],{"class":1100,"line":2507},[1098,14164,2016],{"class":1111},[1098,14166,4386],{"class":1388},[1098,14168,14169],{"class":1100,"line":2524},[1098,14170,1282],{"class":1115},[1098,14172,14173,14175,14178,14180,14182,14184,14186],{"class":1100,"line":2529},[1098,14174,1288],{"class":1247},[1098,14176,14177],{"class":1291}," get_client_ip",[1098,14179,1255],{"class":1133},[1098,14181,1298],{"class":1297},[1098,14183,1134],{"class":1133},[1098,14185,1304],{"class":1303},[1098,14187,1262],{"class":1133},[1098,14189,14190,14192,14195],{"class":1100,"line":2535},[1098,14191,1835],{"class":1268},[1098,14193,14194],{"class":1272},"Get client IP address",[1098,14196,1276],{"class":1268},[1098,14198,14199,14202,14204,14206,14208,14210,14212,14214,14216,14218,14221,14223],{"class":1100,"line":2557},[1098,14200,14201],{"class":1115},"        x_forwarded_for ",[1098,14203,1229],{"class":1133},[1098,14205,1304],{"class":1115},[1098,14207,1148],{"class":1133},[1098,14209,1322],{"class":1321},[1098,14211,1148],{"class":1133},[1098,14213,1327],{"class":1232},[1098,14215,1255],{"class":1133},[1098,14217,1333],{"class":1332},[1098,14219,14220],{"class":1336},"HTTP_X_FORWARDED_FOR",[1098,14222,1333],{"class":1332},[1098,14224,1342],{"class":1133},[1098,14226,14227,14229,14232],{"class":1100,"line":2574},[1098,14228,1348],{"class":1111},[1098,14230,14231],{"class":1115}," x_forwarded_for",[1098,14233,1441],{"class":1133},[1098,14235,14236,14239,14241,14243,14245,14247,14249,14251,14253,14255,14257,14260],{"class":1100,"line":2591},[1098,14237,14238],{"class":1115},"            ip ",[1098,14240,1229],{"class":1133},[1098,14242,14231],{"class":1115},[1098,14244,1148],{"class":1133},[1098,14246,1410],{"class":1232},[1098,14248,1255],{"class":1133},[1098,14250,1333],{"class":1332},[1098,14252,1134],{"class":1336},[1098,14254,1333],{"class":1332},[1098,14256,1420],{"class":1133},[1098,14258,14259],{"class":1423},"0",[1098,14261,1427],{"class":1133},[1098,14263,14264,14266],{"class":1100,"line":2604},[1098,14265,4989],{"class":1111},[1098,14267,1441],{"class":1133},[1098,14269,14270,14272,14274,14276,14278,14280,14282,14284,14286,14288,14291,14293],{"class":1100,"line":2624},[1098,14271,14238],{"class":1115},[1098,14273,1229],{"class":1133},[1098,14275,1304],{"class":1115},[1098,14277,1148],{"class":1133},[1098,14279,1322],{"class":1321},[1098,14281,1148],{"class":1133},[1098,14283,1327],{"class":1232},[1098,14285,1255],{"class":1133},[1098,14287,1333],{"class":1332},[1098,14289,14290],{"class":1336},"REMOTE_ADDR",[1098,14292,1333],{"class":1332},[1098,14294,1342],{"class":1133},[1098,14296,14297,14299],{"class":1100,"line":2629},[1098,14298,2016],{"class":1111},[1098,14300,14301],{"class":1115}," ip\n",[1098,14303,14304],{"class":1100,"line":2651},[1098,14305,1282],{"class":1115},[1098,14307,14308,14310,14313,14315,14317,14319,14321,14323,14326,14328,14331],{"class":1100,"line":2666},[1098,14309,1288],{"class":1247},[1098,14311,14312],{"class":1291}," log_security_event",[1098,14314,1255],{"class":1133},[1098,14316,1298],{"class":1297},[1098,14318,1134],{"class":1133},[1098,14320,1304],{"class":1303},[1098,14322,1134],{"class":1133},[1098,14324,14325],{"class":1303}," event_type",[1098,14327,1134],{"class":1133},[1098,14329,14330],{"class":1303}," details",[1098,14332,1262],{"class":1133},[1098,14334,14335,14337,14340],{"class":1100,"line":2682},[1098,14336,1835],{"class":1268},[1098,14338,14339],{"class":1272},"Log security event",[1098,14341,1276],{"class":1268},[1098,14343,14344,14347,14349],{"class":1100,"line":2692},[1098,14345,14346],{"class":1115},"        event_data ",[1098,14348,1229],{"class":1133},[1098,14350,1851],{"class":1133},[1098,14352,14353,14355,14357,14359,14361,14363,14365,14367],{"class":1100,"line":2721},[1098,14354,1857],{"class":1332},[1098,14356,5343],{"class":1336},[1098,14358,1333],{"class":1332},[1098,14360,1864],{"class":1133},[1098,14362,5355],{"class":1115},[1098,14364,1148],{"class":1133},[1098,14366,5360],{"class":1232},[1098,14368,1979],{"class":1133},[1098,14370,14371,14373,14376,14378,14380,14382],{"class":1100,"line":2750},[1098,14372,1857],{"class":1332},[1098,14374,14375],{"class":1336},"event_type",[1098,14377,1333],{"class":1332},[1098,14379,1864],{"class":1133},[1098,14381,14325],{"class":1115},[1098,14383,1873],{"class":1133},[1098,14385,14386,14388,14391,14393,14395,14397,14400,14402],{"class":1100,"line":2755},[1098,14387,1857],{"class":1332},[1098,14389,14390],{"class":1336},"service",[1098,14392,1333],{"class":1332},[1098,14394,1864],{"class":1133},[1098,14396,1417],{"class":1332},[1098,14398,14399],{"class":1336},"user-service",[1098,14401,1333],{"class":1332},[1098,14403,1873],{"class":1133},[1098,14405,14406,14408,14411,14413,14415],{"class":1100,"line":2775},[1098,14407,1857],{"class":1332},[1098,14409,14410],{"class":1336},"details",[1098,14412,1333],{"class":1332},[1098,14414,1864],{"class":1133},[1098,14416,14417],{"class":1115}," details\n",[1098,14419,14420],{"class":1100,"line":2785},[1098,14421,2005],{"class":1133},[1098,14423,14424],{"class":1100,"line":2812},[1098,14425,1395],{"class":1115},[1098,14427,14428,14431,14433,14436,14438,14440,14442,14444,14446,14449],{"class":1100,"line":2828},[1098,14429,14430],{"class":1115},"        security_logger",[1098,14432,1148],{"class":1133},[1098,14434,14435],{"class":1232},"warning",[1098,14437,1255],{"class":1133},[1098,14439,3934],{"class":1232},[1098,14441,1148],{"class":1133},[1098,14443,11060],{"class":1232},[1098,14445,1255],{"class":1133},[1098,14447,14448],{"class":1232},"event_data",[1098,14450,4465],{"class":1133},[1098,14452,14453],{"class":1100,"line":2833},[1098,14454,1220],{"emptyLinePlaceholder":1219},[1098,14456,14457],{"class":1100,"line":2838},[1098,14458,14459],{"class":1104},"# Intrusion detection\n",[1098,14461,14462,14464,14467],{"class":1100,"line":2866},[1098,14463,1248],{"class":1247},[1098,14465,14466],{"class":1251}," IntrusionDetectionSystem",[1098,14468,1441],{"class":1133},[1098,14470,14471,14473,14476],{"class":1100,"line":2877},[1098,14472,1269],{"class":1268},[1098,14474,14475],{"class":1272},"Simple intrusion detection system",[1098,14477,1276],{"class":1268},[1098,14479,14480],{"class":1100,"line":2886},[1098,14481,1282],{"class":1115},[1098,14483,14484,14486,14488,14490,14492],{"class":1100,"line":2910},[1098,14485,1288],{"class":1247},[1098,14487,5800],{"class":4766},[1098,14489,1255],{"class":1133},[1098,14491,1298],{"class":1297},[1098,14493,1262],{"class":1133},[1098,14495,14496,14498,14500,14503,14505],{"class":1100,"line":2924},[1098,14497,5815],{"class":3697},[1098,14499,1148],{"class":1133},[1098,14501,14502],{"class":1598},"failed_attempts",[1098,14504,5822],{"class":1133},[1098,14506,8252],{"class":1133},[1098,14508,14509,14511,14513,14516,14518,14520],{"class":1100,"line":2929},[1098,14510,5815],{"class":3697},[1098,14512,1148],{"class":1133},[1098,14514,14515],{"class":1598},"blocked_ips",[1098,14517,5822],{"class":1133},[1098,14519,4425],{"class":1814},[1098,14521,1236],{"class":1133},[1098,14523,14524],{"class":1100,"line":2934},[1098,14525,1282],{"class":1115},[1098,14527,14528,14530,14533,14535,14537,14539,14542],{"class":1100,"line":2955},[1098,14529,1288],{"class":1247},[1098,14531,14532],{"class":1291}," record_failed_attempt",[1098,14534,1255],{"class":1133},[1098,14536,1298],{"class":1297},[1098,14538,1134],{"class":1133},[1098,14540,14541],{"class":1303}," ip_address",[1098,14543,1262],{"class":1133},[1098,14545,14546,14548,14551],{"class":1100,"line":2976},[1098,14547,1835],{"class":1268},[1098,14549,14550],{"class":1272},"Record failed authentication attempt",[1098,14552,1276],{"class":1268},[1098,14554,14555,14557,14560,14563,14565,14567,14569,14571],{"class":1100,"line":2981},[1098,14556,1348],{"class":1111},[1098,14558,14559],{"class":1115}," ip_address ",[1098,14561,14562],{"class":1351},"not",[1098,14564,4941],{"class":1351},[1098,14566,3698],{"class":3697},[1098,14568,1148],{"class":1133},[1098,14570,14502],{"class":1598},[1098,14572,1441],{"class":1133},[1098,14574,14575,14577,14579,14581,14583,14585,14587,14589],{"class":1100,"line":2992},[1098,14576,7381],{"class":3697},[1098,14578,1148],{"class":1133},[1098,14580,14502],{"class":1598},[1098,14582,3327],{"class":1133},[1098,14584,13274],{"class":1598},[1098,14586,6168],{"class":1133},[1098,14588,5822],{"class":1133},[1098,14590,4323],{"class":1133},[1098,14592,14593],{"class":1100,"line":3010},[1098,14594,1395],{"class":1115},[1098,14596,14597,14599,14601,14603,14605,14607,14610,14613,14615,14617,14619,14621],{"class":1100,"line":3027},[1098,14598,5815],{"class":3697},[1098,14600,1148],{"class":1133},[1098,14602,14502],{"class":1598},[1098,14604,3327],{"class":1133},[1098,14606,13274],{"class":1598},[1098,14608,14609],{"class":1133},"].",[1098,14611,14612],{"class":1232},"append",[1098,14614,1255],{"class":1133},[1098,14616,5360],{"class":1232},[1098,14618,1148],{"class":1133},[1098,14620,5360],{"class":1232},[1098,14622,6019],{"class":1133},[1098,14624,14625],{"class":1100,"line":3040},[1098,14626,1395],{"class":1115},[1098,14628,14629],{"class":1100,"line":3059},[1098,14630,14631],{"class":1104},"        # Remove old attempts (older than 1 hour)\n",[1098,14633,14634,14637,14639,14641,14643,14645,14647,14649],{"class":1100,"line":3078},[1098,14635,14636],{"class":1115},"        cutoff_time ",[1098,14638,1229],{"class":1133},[1098,14640,5355],{"class":1115},[1098,14642,1148],{"class":1133},[1098,14644,5360],{"class":1232},[1098,14646,1935],{"class":1133},[1098,14648,7367],{"class":1351},[1098,14650,14651],{"class":1423}," 3600\n",[1098,14653,14654,14656,14658,14660,14662,14664,14666,14668],{"class":1100,"line":3096},[1098,14655,5815],{"class":3697},[1098,14657,1148],{"class":1133},[1098,14659,14502],{"class":1598},[1098,14661,3327],{"class":1133},[1098,14663,13274],{"class":1598},[1098,14665,6168],{"class":1133},[1098,14667,5822],{"class":1133},[1098,14669,8355],{"class":1133},[1098,14671,14672,14675,14678,14681,14683,14685,14687,14689,14691,14693],{"class":1100,"line":3101},[1098,14673,14674],{"class":1115},"            attempt ",[1098,14676,14677],{"class":1111},"for",[1098,14679,14680],{"class":1115}," attempt ",[1098,14682,5027],{"class":1111},[1098,14684,3698],{"class":3697},[1098,14686,1148],{"class":1133},[1098,14688,14502],{"class":1598},[1098,14690,3327],{"class":1133},[1098,14692,13274],{"class":1598},[1098,14694,1427],{"class":1133},[1098,14696,14697,14699,14701,14703],{"class":1100,"line":3107},[1098,14698,1550],{"class":1111},[1098,14700,14680],{"class":1115},[1098,14702,8731],{"class":1351},[1098,14704,14705],{"class":1115}," cutoff_time\n",[1098,14707,14708],{"class":1100,"line":3112},[1098,14709,8549],{"class":1133},[1098,14711,14712],{"class":1100,"line":3129},[1098,14713,1395],{"class":1115},[1098,14715,14716],{"class":1100,"line":3142},[1098,14717,14718],{"class":1104},"        # Block IP if too many failed attempts\n",[1098,14720,14721,14723,14725,14727,14729,14731,14733,14735,14737,14740,14742,14745],{"class":1100,"line":3155},[1098,14722,1348],{"class":1111},[1098,14724,7403],{"class":4766},[1098,14726,1255],{"class":1133},[1098,14728,1298],{"class":3697},[1098,14730,1148],{"class":1133},[1098,14732,14502],{"class":1598},[1098,14734,3327],{"class":1133},[1098,14736,13274],{"class":1598},[1098,14738,14739],{"class":1133},"])",[1098,14741,7416],{"class":1351},[1098,14743,14744],{"class":1423}," 5",[1098,14746,1441],{"class":1133},[1098,14748,14749,14751,14753,14755,14757,14760,14762,14764],{"class":1100,"line":3165},[1098,14750,7381],{"class":3697},[1098,14752,1148],{"class":1133},[1098,14754,14515],{"class":1598},[1098,14756,1148],{"class":1133},[1098,14758,14759],{"class":1232},"add",[1098,14761,1255],{"class":1133},[1098,14763,13274],{"class":1232},[1098,14765,1342],{"class":1133},[1098,14767,14768],{"class":1100,"line":3192},[1098,14769,1518],{"class":1115},[1098,14771,14772,14775,14777,14780,14782,14784,14786,14788],{"class":1100,"line":3197},[1098,14773,14774],{"class":1115},"            security_logger",[1098,14776,1148],{"class":1133},[1098,14778,14779],{"class":1232},"critical",[1098,14781,1255],{"class":1133},[1098,14783,3934],{"class":1232},[1098,14785,1148],{"class":1133},[1098,14787,11060],{"class":1232},[1098,14789,2989],{"class":1133},[1098,14791,14792,14794,14796,14798,14800,14802,14805,14807],{"class":1100,"line":3208},[1098,14793,4103],{"class":1332},[1098,14795,14375],{"class":1336},[1098,14797,1333],{"class":1332},[1098,14799,1864],{"class":1133},[1098,14801,1417],{"class":1332},[1098,14803,14804],{"class":1336},"IP_BLOCKED",[1098,14806,1333],{"class":1332},[1098,14808,1873],{"class":1133},[1098,14810,14811,14813,14815,14817,14819,14821],{"class":1100,"line":3217},[1098,14812,4103],{"class":1332},[1098,14814,13274],{"class":1336},[1098,14816,1333],{"class":1332},[1098,14818,1864],{"class":1133},[1098,14820,14541],{"class":1232},[1098,14822,1873],{"class":1133},[1098,14824,14825,14827,14829,14831,14833,14835,14837,14839,14841,14843,14845,14847],{"class":1100,"line":3241},[1098,14826,4103],{"class":1332},[1098,14828,14502],{"class":1336},[1098,14830,1333],{"class":1332},[1098,14832,1864],{"class":1133},[1098,14834,7403],{"class":4766},[1098,14836,1255],{"class":1133},[1098,14838,1298],{"class":3697},[1098,14840,1148],{"class":1133},[1098,14842,14502],{"class":1598},[1098,14844,3327],{"class":1133},[1098,14846,13274],{"class":1598},[1098,14848,14849],{"class":1133},"]),\n",[1098,14851,14852,14854,14856,14858,14860,14862,14864,14866],{"class":1100,"line":3254},[1098,14853,4103],{"class":1332},[1098,14855,5343],{"class":1336},[1098,14857,1333],{"class":1332},[1098,14859,1864],{"class":1133},[1098,14861,5355],{"class":1232},[1098,14863,1148],{"class":1133},[1098,14865,5360],{"class":1232},[1098,14867,1236],{"class":1133},[1098,14869,14870],{"class":1100,"line":3259},[1098,14871,14872],{"class":1133},"            }))\n",[1098,14874,14875],{"class":1100,"line":3264},[1098,14876,1282],{"class":1115},[1098,14878,14879,14881,14884,14886,14888,14890,14892],{"class":1100,"line":3272},[1098,14880,1288],{"class":1247},[1098,14882,14883],{"class":1291}," is_blocked",[1098,14885,1255],{"class":1133},[1098,14887,1298],{"class":1297},[1098,14889,1134],{"class":1133},[1098,14891,14541],{"class":1303},[1098,14893,1262],{"class":1133},[1098,14895,14896,14898,14901],{"class":1100,"line":3300},[1098,14897,1835],{"class":1268},[1098,14899,14900],{"class":1272},"Check if IP is blocked",[1098,14902,1276],{"class":1268},[1098,14904,14905,14907,14909,14911,14913,14915],{"class":1100,"line":3338},[1098,14906,2016],{"class":1111},[1098,14908,14559],{"class":1115},[1098,14910,5027],{"class":1351},[1098,14912,3698],{"class":3697},[1098,14914,1148],{"class":1133},[1098,14916,14917],{"class":1598},"blocked_ips\n",[1098,14919,14920],{"class":1100,"line":3343},[1098,14921,1282],{"class":1115},[1098,14923,14924,14926,14929,14931,14933,14935,14937],{"class":1100,"line":3363},[1098,14925,1288],{"class":1247},[1098,14927,14928],{"class":1291}," unblock_ip",[1098,14930,1255],{"class":1133},[1098,14932,1298],{"class":1297},[1098,14934,1134],{"class":1133},[1098,14936,14541],{"class":1303},[1098,14938,1262],{"class":1133},[1098,14940,14941,14943,14946],{"class":1100,"line":3368},[1098,14942,1835],{"class":1268},[1098,14944,14945],{"class":1272},"Unblock IP address",[1098,14947,1276],{"class":1268},[1098,14949,14950,14952,14954,14956,14958,14961,14963,14965],{"class":1100,"line":3377},[1098,14951,5815],{"class":3697},[1098,14953,1148],{"class":1133},[1098,14955,14515],{"class":1598},[1098,14957,1148],{"class":1133},[1098,14959,14960],{"class":1232},"discard",[1098,14962,1255],{"class":1133},[1098,14964,13274],{"class":1232},[1098,14966,1342],{"class":1133},[1098,14968,14969,14971,14973,14975,14977,14979,14981],{"class":1100,"line":3391},[1098,14970,1348],{"class":1111},[1098,14972,14559],{"class":1115},[1098,14974,5027],{"class":1351},[1098,14976,3698],{"class":3697},[1098,14978,1148],{"class":1133},[1098,14980,14502],{"class":1598},[1098,14982,1441],{"class":1133},[1098,14984,14985,14988,14990,14992,14994,14996,14998],{"class":1100,"line":3397},[1098,14986,14987],{"class":1111},"            del",[1098,14989,3698],{"class":3697},[1098,14991,1148],{"class":1133},[1098,14993,14502],{"class":1598},[1098,14995,3327],{"class":1133},[1098,14997,13274],{"class":1598},[1098,14999,1427],{"class":1133},[1098,15001,15002],{"class":1100,"line":3402},[1098,15003,1220],{"emptyLinePlaceholder":1219},[1098,15005,15006,15009,15011,15013],{"class":1100,"line":3431},[1098,15007,15008],{"class":1115},"ids ",[1098,15010,1229],{"class":1133},[1098,15012,14466],{"class":1232},[1098,15014,1236],{"class":1133},[1035,15016,15018],{"id":15017},"_2-security-metrics","2. Security Metrics",[1088,15020,15022],{"className":1090,"code":15021,"language":1092,"meta":1093,"style":1093},"# security_metrics.py\nfrom prometheus_client import Counter, Histogram, Gauge\nimport time\n\n# Security metrics\nSECURITY_EVENTS = Counter(\n    'security_events_total',\n    'Total security events',\n    ['event_type', 'service']\n)\n\nAUTH_FAILURES = Counter(\n    'auth_failures_total',\n    'Total authentication failures',\n    ['service', 'reason']\n)\n\nBLOCKED_REQUESTS = Counter(\n    'blocked_requests_total',\n    'Total blocked requests',\n    ['service', 'reason']\n)\n\nACTIVE_SESSIONS = Gauge(\n    'active_sessions',\n    'Number of active user sessions',\n    ['service']\n)\n\nclass SecurityMetricsCollector:\n    \"\"\"Collect security metrics\"\"\"\n    \n    @staticmethod\n    def record_security_event(event_type, service='user-service'):\n        \"\"\"Record security event\"\"\"\n        SECURITY_EVENTS.labels(event_type=event_type, service=service).inc()\n    \n    @staticmethod\n    def record_auth_failure(reason, service='user-service'):\n        \"\"\"Record authentication failure\"\"\"\n        AUTH_FAILURES.labels(service=service, reason=reason).inc()\n    \n    @staticmethod\n    def record_blocked_request(reason, service='user-service'):\n        \"\"\"Record blocked request\"\"\"\n        BLOCKED_REQUESTS.labels(service=service, reason=reason).inc()\n    \n    @staticmethod\n    def update_active_sessions(count, service='user-service'):\n        \"\"\"Update active sessions count\"\"\"\n        ACTIVE_SESSIONS.labels(service=service).set(count)\n\n# Usage in middleware\nclass SecurityMetricsMiddleware(MiddlewareMixin):\n    \"\"\"Collect security metrics\"\"\"\n    \n    def __call__(self, request):\n        response = self.get_response(request)\n        \n        # Record metrics based on response\n        if response.status_code == 401:\n            SecurityMetricsCollector.record_auth_failure('invalid_credentials')\n        elif response.status_code == 403:\n            SecurityMetricsCollector.record_blocked_request('forbidden')\n        elif response.status_code == 429:\n            SecurityMetricsCollector.record_blocked_request('rate_limit')\n        \n        return response\n",[1095,15023,15024,15029,15051,15057,15061,15066,15077,15089,15100,15121,15125,15129,15140,15151,15162,15183,15187,15191,15202,15213,15224,15244,15248,15252,15264,15275,15286,15298,15302,15306,15315,15324,15328,15334,15360,15369,15402,15406,15412,15437,15446,15478,15482,15488,15513,15522,15553,15557,15563,15589,15598,15625,15629,15634,15647,15655,15659,15675,15693,15697,15702,15718,15739,15756,15776,15793,15812,15816],{"__ignoreMap":1093},[1098,15025,15026],{"class":1100,"line":1101},[1098,15027,15028],{"class":1104},"# security_metrics.py\n",[1098,15030,15031,15033,15036,15038,15041,15043,15046,15048],{"class":1100,"line":1108},[1098,15032,1122],{"class":1111},[1098,15034,15035],{"class":1115}," prometheus_client ",[1098,15037,1112],{"class":1111},[1098,15039,15040],{"class":1115}," Counter",[1098,15042,1134],{"class":1133},[1098,15044,15045],{"class":1115}," Histogram",[1098,15047,1134],{"class":1133},[1098,15049,15050],{"class":1115}," Gauge\n",[1098,15052,15053,15055],{"class":1100,"line":1119},[1098,15054,1112],{"class":1111},[1098,15056,5071],{"class":1115},[1098,15058,15059],{"class":1100,"line":1140},[1098,15060,1220],{"emptyLinePlaceholder":1219},[1098,15062,15063],{"class":1100,"line":1159},[1098,15064,15065],{"class":1104},"# Security metrics\n",[1098,15067,15068,15071,15073,15075],{"class":1100,"line":1181},[1098,15069,15070],{"class":3697},"SECURITY_EVENTS",[1098,15072,5822],{"class":1133},[1098,15074,15040],{"class":1232},[1098,15076,1460],{"class":1133},[1098,15078,15079,15082,15085,15087],{"class":1100,"line":1199},[1098,15080,15081],{"class":1332},"    '",[1098,15083,15084],{"class":1336},"security_events_total",[1098,15086,1333],{"class":1332},[1098,15088,1873],{"class":1133},[1098,15090,15091,15093,15096,15098],{"class":1100,"line":1216},[1098,15092,15081],{"class":1332},[1098,15094,15095],{"class":1336},"Total security events",[1098,15097,1333],{"class":1332},[1098,15099,1873],{"class":1133},[1098,15101,15102,15105,15107,15109,15111,15113,15115,15117,15119],{"class":1100,"line":1223},[1098,15103,15104],{"class":1133},"    [",[1098,15106,1333],{"class":1332},[1098,15108,14375],{"class":1336},[1098,15110,1333],{"class":1332},[1098,15112,1134],{"class":1133},[1098,15114,1417],{"class":1332},[1098,15116,14390],{"class":1336},[1098,15118,1333],{"class":1332},[1098,15120,1427],{"class":1133},[1098,15122,15123],{"class":1100,"line":1239},[1098,15124,1342],{"class":1133},[1098,15126,15127],{"class":1100,"line":1244},[1098,15128,1220],{"emptyLinePlaceholder":1219},[1098,15130,15131,15134,15136,15138],{"class":1100,"line":1265},[1098,15132,15133],{"class":3697},"AUTH_FAILURES",[1098,15135,5822],{"class":1133},[1098,15137,15040],{"class":1232},[1098,15139,1460],{"class":1133},[1098,15141,15142,15144,15147,15149],{"class":1100,"line":1279},[1098,15143,15081],{"class":1332},[1098,15145,15146],{"class":1336},"auth_failures_total",[1098,15148,1333],{"class":1332},[1098,15150,1873],{"class":1133},[1098,15152,15153,15155,15158,15160],{"class":1100,"line":1285},[1098,15154,15081],{"class":1332},[1098,15156,15157],{"class":1336},"Total authentication failures",[1098,15159,1333],{"class":1332},[1098,15161,1873],{"class":1133},[1098,15163,15164,15166,15168,15170,15172,15174,15176,15179,15181],{"class":1100,"line":1309},[1098,15165,15104],{"class":1133},[1098,15167,1333],{"class":1332},[1098,15169,14390],{"class":1336},[1098,15171,1333],{"class":1332},[1098,15173,1134],{"class":1133},[1098,15175,1417],{"class":1332},[1098,15177,15178],{"class":1336},"reason",[1098,15180,1333],{"class":1332},[1098,15182,1427],{"class":1133},[1098,15184,15185],{"class":1100,"line":1345},[1098,15186,1342],{"class":1133},[1098,15188,15189],{"class":1100,"line":1382},[1098,15190,1220],{"emptyLinePlaceholder":1219},[1098,15192,15193,15196,15198,15200],{"class":1100,"line":1392},[1098,15194,15195],{"class":3697},"BLOCKED_REQUESTS",[1098,15197,5822],{"class":1133},[1098,15199,15040],{"class":1232},[1098,15201,1460],{"class":1133},[1098,15203,15204,15206,15209,15211],{"class":1100,"line":1398},[1098,15205,15081],{"class":1332},[1098,15207,15208],{"class":1336},"blocked_requests_total",[1098,15210,1333],{"class":1332},[1098,15212,1873],{"class":1133},[1098,15214,15215,15217,15220,15222],{"class":1100,"line":1430},[1098,15216,15081],{"class":1332},[1098,15218,15219],{"class":1336},"Total blocked requests",[1098,15221,1333],{"class":1332},[1098,15223,1873],{"class":1133},[1098,15225,15226,15228,15230,15232,15234,15236,15238,15240,15242],{"class":1100,"line":1435},[1098,15227,15104],{"class":1133},[1098,15229,1333],{"class":1332},[1098,15231,14390],{"class":1336},[1098,15233,1333],{"class":1332},[1098,15235,1134],{"class":1133},[1098,15237,1417],{"class":1332},[1098,15239,15178],{"class":1336},[1098,15241,1333],{"class":1332},[1098,15243,1427],{"class":1133},[1098,15245,15246],{"class":1100,"line":1444},[1098,15247,1342],{"class":1133},[1098,15249,15250],{"class":1100,"line":1463},[1098,15251,1220],{"emptyLinePlaceholder":1219},[1098,15253,15254,15257,15259,15262],{"class":1100,"line":1474},[1098,15255,15256],{"class":3697},"ACTIVE_SESSIONS",[1098,15258,5822],{"class":1133},[1098,15260,15261],{"class":1232}," Gauge",[1098,15263,1460],{"class":1133},[1098,15265,15266,15268,15271,15273],{"class":1100,"line":1489},[1098,15267,15081],{"class":1332},[1098,15269,15270],{"class":1336},"active_sessions",[1098,15272,1333],{"class":1332},[1098,15274,1873],{"class":1133},[1098,15276,15277,15279,15282,15284],{"class":1100,"line":1509},[1098,15278,15081],{"class":1332},[1098,15280,15281],{"class":1336},"Number of active user sessions",[1098,15283,1333],{"class":1332},[1098,15285,1873],{"class":1133},[1098,15287,15288,15290,15292,15294,15296],{"class":1100,"line":1515},[1098,15289,15104],{"class":1133},[1098,15291,1333],{"class":1332},[1098,15293,14390],{"class":1336},[1098,15295,1333],{"class":1332},[1098,15297,1427],{"class":1133},[1098,15299,15300],{"class":1100,"line":1521},[1098,15301,1342],{"class":1133},[1098,15303,15304],{"class":1100,"line":1547},[1098,15305,1220],{"emptyLinePlaceholder":1219},[1098,15307,15308,15310,15313],{"class":1100,"line":1560},[1098,15309,1248],{"class":1247},[1098,15311,15312],{"class":1251}," SecurityMetricsCollector",[1098,15314,1441],{"class":1133},[1098,15316,15317,15319,15322],{"class":1100,"line":1580},[1098,15318,1269],{"class":1268},[1098,15320,15321],{"class":1272},"Collect security metrics",[1098,15323,1276],{"class":1268},[1098,15325,15326],{"class":1100,"line":1585},[1098,15327,1282],{"class":1115},[1098,15329,15330,15332],{"class":1100,"line":1617},[1098,15331,1811],{"class":1133},[1098,15333,1815],{"class":1814},[1098,15335,15336,15338,15341,15343,15345,15347,15350,15352,15354,15356,15358],{"class":1100,"line":1634},[1098,15337,1288],{"class":1247},[1098,15339,15340],{"class":1291}," record_security_event",[1098,15342,1255],{"class":1133},[1098,15344,14375],{"class":1303},[1098,15346,1134],{"class":1133},[1098,15348,15349],{"class":1303}," service",[1098,15351,1229],{"class":1351},[1098,15353,1333],{"class":1332},[1098,15355,14399],{"class":1336},[1098,15357,1333],{"class":1332},[1098,15359,1262],{"class":1133},[1098,15361,15362,15364,15367],{"class":1100,"line":1652},[1098,15363,1835],{"class":1268},[1098,15365,15366],{"class":1272},"Record security event",[1098,15368,1276],{"class":1268},[1098,15370,15371,15374,15376,15379,15381,15383,15385,15387,15389,15391,15393,15395,15397,15400],{"class":1100,"line":1657},[1098,15372,15373],{"class":3697},"        SECURITY_EVENTS",[1098,15375,1148],{"class":1133},[1098,15377,15378],{"class":1232},"labels",[1098,15380,1255],{"class":1133},[1098,15382,14375],{"class":1492},[1098,15384,1229],{"class":1133},[1098,15386,14375],{"class":1232},[1098,15388,1134],{"class":1133},[1098,15390,15349],{"class":1492},[1098,15392,1229],{"class":1133},[1098,15394,14390],{"class":1232},[1098,15396,4738],{"class":1133},[1098,15398,15399],{"class":1232},"inc",[1098,15401,1236],{"class":1133},[1098,15403,15404],{"class":1100,"line":1675},[1098,15405,1282],{"class":1115},[1098,15407,15408,15410],{"class":1100,"line":1680},[1098,15409,1811],{"class":1133},[1098,15411,1815],{"class":1814},[1098,15413,15414,15416,15419,15421,15423,15425,15427,15429,15431,15433,15435],{"class":1100,"line":1695},[1098,15415,1288],{"class":1247},[1098,15417,15418],{"class":1291}," record_auth_failure",[1098,15420,1255],{"class":1133},[1098,15422,15178],{"class":1303},[1098,15424,1134],{"class":1133},[1098,15426,15349],{"class":1303},[1098,15428,1229],{"class":1351},[1098,15430,1333],{"class":1332},[1098,15432,14399],{"class":1336},[1098,15434,1333],{"class":1332},[1098,15436,1262],{"class":1133},[1098,15438,15439,15441,15444],{"class":1100,"line":1714},[1098,15440,1835],{"class":1268},[1098,15442,15443],{"class":1272},"Record authentication failure",[1098,15445,1276],{"class":1268},[1098,15447,15448,15451,15453,15455,15457,15459,15461,15463,15465,15468,15470,15472,15474,15476],{"class":1100,"line":1728},[1098,15449,15450],{"class":3697},"        AUTH_FAILURES",[1098,15452,1148],{"class":1133},[1098,15454,15378],{"class":1232},[1098,15456,1255],{"class":1133},[1098,15458,14390],{"class":1492},[1098,15460,1229],{"class":1133},[1098,15462,14390],{"class":1232},[1098,15464,1134],{"class":1133},[1098,15466,15467],{"class":1492}," reason",[1098,15469,1229],{"class":1133},[1098,15471,15178],{"class":1232},[1098,15473,4738],{"class":1133},[1098,15475,15399],{"class":1232},[1098,15477,1236],{"class":1133},[1098,15479,15480],{"class":1100,"line":1746},[1098,15481,1282],{"class":1115},[1098,15483,15484,15486],{"class":1100,"line":1760},[1098,15485,1811],{"class":1133},[1098,15487,1815],{"class":1814},[1098,15489,15490,15492,15495,15497,15499,15501,15503,15505,15507,15509,15511],{"class":1100,"line":1778},[1098,15491,1288],{"class":1247},[1098,15493,15494],{"class":1291}," record_blocked_request",[1098,15496,1255],{"class":1133},[1098,15498,15178],{"class":1303},[1098,15500,1134],{"class":1133},[1098,15502,15349],{"class":1303},[1098,15504,1229],{"class":1351},[1098,15506,1333],{"class":1332},[1098,15508,14399],{"class":1336},[1098,15510,1333],{"class":1332},[1098,15512,1262],{"class":1133},[1098,15514,15515,15517,15520],{"class":1100,"line":1783},[1098,15516,1835],{"class":1268},[1098,15518,15519],{"class":1272},"Record blocked request",[1098,15521,1276],{"class":1268},[1098,15523,15524,15527,15529,15531,15533,15535,15537,15539,15541,15543,15545,15547,15549,15551],{"class":1100,"line":1793},[1098,15525,15526],{"class":3697},"        BLOCKED_REQUESTS",[1098,15528,1148],{"class":1133},[1098,15530,15378],{"class":1232},[1098,15532,1255],{"class":1133},[1098,15534,14390],{"class":1492},[1098,15536,1229],{"class":1133},[1098,15538,14390],{"class":1232},[1098,15540,1134],{"class":1133},[1098,15542,15467],{"class":1492},[1098,15544,1229],{"class":1133},[1098,15546,15178],{"class":1232},[1098,15548,4738],{"class":1133},[1098,15550,15399],{"class":1232},[1098,15552,1236],{"class":1133},[1098,15554,15555],{"class":1100,"line":1803},[1098,15556,1282],{"class":1115},[1098,15558,15559,15561],{"class":1100,"line":1808},[1098,15560,1811],{"class":1133},[1098,15562,1815],{"class":1814},[1098,15564,15565,15567,15570,15572,15575,15577,15579,15581,15583,15585,15587],{"class":1100,"line":1818},[1098,15566,1288],{"class":1247},[1098,15568,15569],{"class":1291}," update_active_sessions",[1098,15571,1255],{"class":1133},[1098,15573,15574],{"class":1303},"count",[1098,15576,1134],{"class":1133},[1098,15578,15349],{"class":1303},[1098,15580,1229],{"class":1351},[1098,15582,1333],{"class":1332},[1098,15584,14399],{"class":1336},[1098,15586,1333],{"class":1332},[1098,15588,1262],{"class":1133},[1098,15590,15591,15593,15596],{"class":1100,"line":1832},[1098,15592,1835],{"class":1268},[1098,15594,15595],{"class":1272},"Update active sessions count",[1098,15597,1276],{"class":1268},[1098,15599,15600,15603,15605,15607,15609,15611,15613,15615,15617,15619,15621,15623],{"class":1100,"line":1843},[1098,15601,15602],{"class":3697},"        ACTIVE_SESSIONS",[1098,15604,1148],{"class":1133},[1098,15606,15378],{"class":1232},[1098,15608,1255],{"class":1133},[1098,15610,14390],{"class":1492},[1098,15612,1229],{"class":1133},[1098,15614,14390],{"class":1232},[1098,15616,4738],{"class":1133},[1098,15618,10903],{"class":1232},[1098,15620,1255],{"class":1133},[1098,15622,15574],{"class":1232},[1098,15624,1342],{"class":1133},[1098,15626,15627],{"class":1100,"line":1854},[1098,15628,1220],{"emptyLinePlaceholder":1219},[1098,15630,15631],{"class":1100,"line":1876},[1098,15632,15633],{"class":1104},"# Usage in middleware\n",[1098,15635,15636,15638,15641,15643,15645],{"class":1100,"line":1896},[1098,15637,1248],{"class":1247},[1098,15639,15640],{"class":1251}," SecurityMetricsMiddleware",[1098,15642,1255],{"class":1133},[1098,15644,12966],{"class":1258},[1098,15646,1262],{"class":1133},[1098,15648,15649,15651,15653],{"class":1100,"line":1916},[1098,15650,1269],{"class":1268},[1098,15652,15321],{"class":1272},[1098,15654,1276],{"class":1268},[1098,15656,15657],{"class":1100,"line":1961},[1098,15658,1282],{"class":1115},[1098,15660,15661,15663,15665,15667,15669,15671,15673],{"class":1100,"line":1982},[1098,15662,1288],{"class":1247},[1098,15664,6850],{"class":4766},[1098,15666,1255],{"class":1133},[1098,15668,1298],{"class":1297},[1098,15670,1134],{"class":1133},[1098,15672,1304],{"class":1303},[1098,15674,1262],{"class":1133},[1098,15676,15677,15679,15681,15683,15685,15687,15689,15691],{"class":1100,"line":2002},[1098,15678,6911],{"class":1115},[1098,15680,1229],{"class":1133},[1098,15682,3698],{"class":3697},[1098,15684,1148],{"class":1133},[1098,15686,6834],{"class":1232},[1098,15688,1255],{"class":1133},[1098,15690,2677],{"class":1232},[1098,15692,1342],{"class":1133},[1098,15694,15695],{"class":1100,"line":2008},[1098,15696,1395],{"class":1115},[1098,15698,15699],{"class":1100,"line":2013},[1098,15700,15701],{"class":1104},"        # Record metrics based on response\n",[1098,15703,15704,15706,15708,15710,15712,15714,15716],{"class":1100,"line":2028},[1098,15705,1348],{"class":1111},[1098,15707,3909],{"class":1115},[1098,15709,1148],{"class":1133},[1098,15711,3914],{"class":1598},[1098,15713,3917],{"class":1351},[1098,15715,13399],{"class":1423},[1098,15717,1441],{"class":1133},[1098,15719,15720,15723,15725,15728,15730,15732,15735,15737],{"class":1100,"line":2038},[1098,15721,15722],{"class":1115},"            SecurityMetricsCollector",[1098,15724,1148],{"class":1133},[1098,15726,15727],{"class":1232},"record_auth_failure",[1098,15729,1255],{"class":1133},[1098,15731,1333],{"class":1332},[1098,15733,15734],{"class":1336},"invalid_credentials",[1098,15736,1333],{"class":1332},[1098,15738,1342],{"class":1133},[1098,15740,15741,15743,15745,15747,15749,15751,15754],{"class":1100,"line":2052},[1098,15742,4932],{"class":1111},[1098,15744,3909],{"class":1115},[1098,15746,1148],{"class":1133},[1098,15748,3914],{"class":1598},[1098,15750,3917],{"class":1351},[1098,15752,15753],{"class":1423}," 403",[1098,15755,1441],{"class":1133},[1098,15757,15758,15760,15762,15765,15767,15769,15772,15774],{"class":1100,"line":2067},[1098,15759,15722],{"class":1115},[1098,15761,1148],{"class":1133},[1098,15763,15764],{"class":1232},"record_blocked_request",[1098,15766,1255],{"class":1133},[1098,15768,1333],{"class":1332},[1098,15770,15771],{"class":1336},"forbidden",[1098,15773,1333],{"class":1332},[1098,15775,1342],{"class":1133},[1098,15777,15778,15780,15782,15784,15786,15788,15791],{"class":1100,"line":2073},[1098,15779,4932],{"class":1111},[1098,15781,3909],{"class":1115},[1098,15783,1148],{"class":1133},[1098,15785,3914],{"class":1598},[1098,15787,3917],{"class":1351},[1098,15789,15790],{"class":1423}," 429",[1098,15792,1441],{"class":1133},[1098,15794,15795,15797,15799,15801,15803,15805,15808,15810],{"class":1100,"line":2078},[1098,15796,15722],{"class":1115},[1098,15798,1148],{"class":1133},[1098,15800,15764],{"class":1232},[1098,15802,1255],{"class":1133},[1098,15804,1333],{"class":1332},[1098,15806,15807],{"class":1336},"rate_limit",[1098,15809,1333],{"class":1332},[1098,15811,1342],{"class":1133},[1098,15813,15814],{"class":1100,"line":2085},[1098,15815,1395],{"class":1115},[1098,15817,15818,15820],{"class":1100,"line":2099},[1098,15819,2016],{"class":1111},[1098,15821,6932],{"class":1115},[1030,15823,15825],{"id":15824},"summary","Summary",[1026,15827,15828],{},"Securing microservices requires a multi-layered approach:",[8222,15830,15831,15837,15842,15847,15852,15857],{},[1043,15832,15833,15836],{},[1046,15834,15835],{},"Authentication",": JWT tokens, OAuth 2.0, service authentication",[1043,15838,15839,15841],{},[1046,15840,3860],{},": Role-based access control, fine-grained permissions",[1043,15843,15844,15846],{},[1046,15845,1060],{},": Network policies, service mesh, mTLS",[1043,15848,15849,15851],{},[1046,15850,1066],{},": Encryption at rest and in transit, secrets management",[1043,15853,15854,15856],{},[1046,15855,1072],{},": Input validation, rate limiting, HTTPS",[1043,15858,15859,15861],{},[1046,15860,1078],{},": Security logging, intrusion detection, metrics",[1026,15863,15864],{},"A comprehensive security strategy protects against various threats while maintaining system performance and usability. In the next section, we'll explore performance optimization with caching.",[15866,15867,15868],"style",{},"html pre.shiki code .s9Tkl, html code.shiki .s9Tkl{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#A0ADA0;--shiki-default-font-style:inherit;--shiki-dark:#758575DD;--shiki-dark-font-style:inherit}html pre.shiki code .siDh9, html code.shiki .siDh9{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#1E754F;--shiki-default-font-style:inherit;--shiki-dark:#4D9375;--shiki-dark-font-style:inherit}html pre.shiki code .sftqT, html code.shiki .sftqT{--shiki-light:#90A4AE;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .soVBu, html code.shiki .soVBu{--shiki-light:#39ADB5;--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .siWMO, html code.shiki .siWMO{--shiki-light:#6182B8;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .s5Kfy, html code.shiki .s5Kfy{--shiki-light:#9C3EDA;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sD-vU, html code.shiki .sD-vU{--shiki-light:#E2931D;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sm7ve, html code.shiki .sm7ve{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#B5695977;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D77;--shiki-dark-font-style:inherit}html pre.shiki code .sVyVU, html code.shiki .sVyVU{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B56959;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D;--shiki-dark-font-style:inherit}html pre.shiki code .sljsM, html code.shiki .sljsM{--shiki-light:#6182B8;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sRjD_, html code.shiki .sRjD_{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sCyAa, html code.shiki .sCyAa{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sFGJz, html code.shiki .sFGJz{--shiki-light:#E53935;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .sVsLi, html code.shiki .sVsLi{--shiki-light:#39ADB5;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .s8XtY, html code.shiki .s8XtY{--shiki-light:#39ADB5;--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .s7CZa, html code.shiki .s7CZa{--shiki-light:#F76D47;--shiki-default:#2F798A;--shiki-dark:#4C9A91}html pre.shiki code .sqOPj, html code.shiki .sqOPj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B07D48;--shiki-default-font-style:inherit;--shiki-dark:#BD976A;--shiki-dark-font-style:inherit}html pre.shiki code .sBPpx, html code.shiki .sBPpx{--shiki-light:#E53935;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .sa2tF, html code.shiki .sa2tF{--shiki-light:#E2931D;--shiki-default:#998418;--shiki-dark:#B8A965}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 .se3Ec, html code.shiki .se3Ec{--shiki-light:#90A4AE;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .s3h35, html code.shiki .s3h35{--shiki-light:#F76D47;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sJdAF, html code.shiki .sJdAF{--shiki-light:#6182B8;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sRJPX, html code.shiki .sRJPX{--shiki-light:#91B859;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .s27EL, html code.shiki .s27EL{--shiki-light:#91B859;--shiki-default:#AB5E3F;--shiki-dark:#C4704F}html pre.shiki code .sGuSu, html code.shiki .sGuSu{--shiki-light:#39ADB5;--shiki-default:#2F798A;--shiki-dark:#4C9A91}html pre.shiki code .sk0MF, html code.shiki .sk0MF{--shiki-light:#90A4AE;--shiki-default:#BDA437;--shiki-dark:#E6CC77}html pre.shiki code .sETVe, html code.shiki .sETVe{--shiki-light:#39ADB5;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sz9Cv, html code.shiki .sz9Cv{--shiki-light:#91B859;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sSC40, html code.shiki .sSC40{--shiki-light:#90A4AE;--shiki-default:#B07D48;--shiki-dark:#BD976A}html pre.shiki code .suXOh, html code.shiki .suXOh{--shiki-light:#E53935;--shiki-default:#998418;--shiki-dark:#B8A965}",{"title":1093,"searchDepth":1101,"depth":1108,"links":15870},[15871,15874,15879,15883,15887,15891,15895,15899],{"id":1032,"depth":1108,"text":1033,"children":15872},[15873],{"id":1037,"depth":1119,"text":1038},{"id":1082,"depth":1108,"text":390,"children":15875},[15876,15877,15878],{"id":1085,"depth":1119,"text":1086},{"id":3484,"depth":1119,"text":3485},{"id":4231,"depth":1119,"text":4232},{"id":5035,"depth":1108,"text":5036,"children":15880},[15881,15882],{"id":5039,"depth":1119,"text":5040},{"id":6334,"depth":1119,"text":6335},{"id":7048,"depth":1108,"text":1072,"children":15884},[15885,15886],{"id":7051,"depth":1119,"text":7052},{"id":7891,"depth":1119,"text":7892},{"id":9352,"depth":1108,"text":1066,"children":15888},[15889,15890],{"id":9355,"depth":1119,"text":9356},{"id":10582,"depth":1119,"text":10583},{"id":11695,"depth":1108,"text":1060,"children":15892},[15893,15894],{"id":11698,"depth":1119,"text":11699},{"id":12422,"depth":1119,"text":12423},{"id":12849,"depth":1108,"text":12850,"children":15896},[15897,15898],{"id":12853,"depth":1119,"text":12854},{"id":15017,"depth":1119,"text":15018},{"id":15824,"depth":1108,"text":15825},"md",null,{},{"title":913,"description":1028},"mxkwA5LyVGnxX7KJDVMnzOPPIsWNDKCVM12FLBBxxxQ",[15906,15908],{"title":909,"path":910,"stem":911,"description":15907,"children":-1},"Deploying microservices requires careful orchestration of multiple services, their dependencies, and infrastructure components. This chapter covers deployment strategies, containerization, orchestration platforms, and best practices for production-ready Django microservices.",{"title":917,"path":918,"stem":919,"description":15909,"children":-1},"Performance optimization in microservices requires a multi-layered approach to caching, from application-level caching to distributed caching strategies. This chapter covers comprehensive caching techniques, performance monitoring, and optimization strategies for Django microservices.",1772474964421]