{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8f11c665",
   "metadata": {},
   "source": [
    "# 22-12 · Automatyczne osłony Jinja\n",
    "\n",
    "Praktyka do sekcji [„Jinja: wzorce HTML z danymi”"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43c012a7",
   "metadata": {},
   "source": [
    "## Cel\n",
    "\n",
    "Upewnij się, że domyślnie Jinja unika potencjalnie niebezpiecznego tekstu i zobacz, co robi filtr | safe."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4586b8b5",
   "metadata": {},
   "source": [
    "## Sprawa robocza"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ea588c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from flask import Flask, render_template_string\n",
    "\n",
    "app = Flask(__name__)\n",
    "\n",
    "opasnyj_tekst = \"<script>alert(1)</script>\"\n",
    "\n",
    "SHABLON = \"<p>{{ tekst }}</p>\"\n",
    "SHABLON_SAFE = \"<p>{{ tekst|safe }}</p>\"\n",
    "\n",
    "\n",
    "@app.route(\"/bez-safe\")\n",
    "def bez_safe():\n",
    "    return render_template_string(SHABLON, tekst=opasnyj_tekst)\n",
    "\n",
    "\n",
    "@app.route(\"/s-safe\")\n",
    "def s_safe():\n",
    "    return render_template_string(SHABLON_SAFE, tekst=opasnyj_tekst)\n",
    "\n",
    "\n",
    "# Obie trasy zostały zarejestrowane przed pierwszym wnioskiem – Flask już nie\n",
    "# pozwala dodawać trasy po tym, jak aplikacja już odpowiedziała\n",
    "# na pierwsze zapytanie.\n",
    "client = app.test_client()\n",
    "\n",
    "otvet = client.get(\"/bez-safe\")\n",
    "telo = otvet.get_data(as_text=True)\n",
    "print(telo)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3d8be4c",
   "metadata": {},
   "source": [
    "## Sprawdzenie wyniku"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "721cb013",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert \"<script>alert(1)</script>\" not in telo\n",
    "assert \"&lt;script&gt;\" in telo\n",
    "print(\"Верно: Jinja экранировала тег script — он показан как текст, а не выполнен.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79f0a99f",
   "metadata": {},
   "source": [
    "## Eksperyment — z |safe oznaczenie przechodzi, jak jest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8fc08df3",
   "metadata": {},
   "outputs": [],
   "source": [
    "otvet2 = client.get(\"/s-safe\")\n",
    "telo2 = otvet2.get_data(as_text=True)\n",
    "\n",
    "assert \"<script>alert(1)</script>\" in telo2\n",
    "print(\"Так и есть: |safe отключает экранирование — поэтому его нельзя применять к вводу, который вы не контролируете.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "name": "python",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
