- пришедшего называет заголовок Remote-User от прокси, и верят ему только с адреса из перечня trusted_proxies; своего входа у сервиса не осталось — ни корня /auth, ни кук, ни срока сессии, ни секрета клиента в конфиге и в базе - учётная запись заводится первым обращением: EnsureUser в пакете хранилища, шаг схемы 202608220001 с колонкой provider_login и снятыми правилами users - cmd/oidcstub заменён на cmd/devtools с подкомандой proxy; заодно закрыт унаследованный DL3066 — пользователь образа назван числом
9.3 KiB
MODIFIED Requirements
Requirement: Неизвестный путь вне корней открывает приложение
Сервис SHALL отдавать разметку приложения на всяком пути, который не принадлежит
ни одному корню сервиса и не совпадает с отдельным адресом наблюдения. Корни
перечислены поимённо — /api у хранилища, /app у приложения, /_ у панели, —
отдельными адресами стоят /health и /metrics.
Корня /auth в перечне больше нет: собственного входа у сервиса не осталось, и
адресов под этим корнем не существует. Прежние адреса входа поэтому отвечают тем
же, чем отвечает всякий путь вне корней, — разметкой приложения. Резервировать имя
за отказом сервис не берётся: имя, за которым ничего не стоит, ничем не отличается
от любого другого свободного имени, а второй перечень «когда-то занятых корней»
разошёлся бы с первым молча.
Путь принадлежит корню, когда совпадает с ним точно либо начинается им вместе с
косой чертой. Оба условия обязательны: по одному лишь префиксу корню /app
достался бы посторонний /apple, а по одному лишь префиксу с косой чертой голый
/api не достался бы никому и уехал бы разметкой.
Путь, принадлежащий корню, MUST не проваливаться в приложение никогда: отказ
контракта остаётся отказом контракта и уходит той формой, которой этот корень
отвечает и сегодня. Иначе программа, ошибшаяся адресом под корнем приложения,
получила бы разметку с кодом 200 вместо отказа с машиночитаемым кодом — и
приняла бы её за ответ.
Путь под каталогом ресурсов — тем, который наполняет сборщик, — разметкой не
подменяется: не совпавший с файлом, он MUST отвечать 404. Иначе разметка
прежней сборки, назвавшая ресурс, которого в новой сборке уже нет, получает на
него 200 и разметку вместо ресурса: браузер отвергнет её по типу содержимого,
человек увидит пустой экран, а в кодах ответов сервиса не останется ничего.
Открывающими страницу считаются GET и HEAD, и только они; прочие методы MUST
отвечать 405.
Scenario: Обновление страницы посреди приложения открывает тот же экран
- GIVEN приложение открыто на своём маршруте
- WHEN браузер спрашивает этот путь заново
- THEN ответ имеет код
200 - AND тело ответа — разметка приложения
Scenario: Голый корень разметкой не подменяется
- WHEN запрос приходит на путь, совпадающий с корнем сервиса точно и без косой черты
- THEN тело ответа — не разметка приложения
Scenario: Посторонний путь, начинающийся именем корня, открывает приложение
- WHEN запрос приходит на путь, который начинается именем корня, но не отделён от него косой чертой
- THEN ответ имеет код
200 - AND тело ответа — разметка приложения
Scenario: Прежний адрес входа открывает приложение
- WHEN запрос приходит на путь под прежним корнем входа
- THEN ответ имеет код
200 - AND тело ответа — разметка приложения
Scenario: Неизвестный путь под корнем приложения отвечает отказом
- GIVEN запрос идёт с заголовком, поставленным прокси
- WHEN он спрашивает неизвестный путь под корнем приложения
- THEN ответ имеет код
404 - AND тело ответа — отказ приложения с машиночитаемым кодом, а не разметка
Scenario: Неизвестный путь под корнем приложения неузнанному отвечает как все прочие его адреса
- WHEN запрос приходит на неизвестный путь под корнем приложения без заголовка
- THEN ответ имеет код
401 - AND тело ответа — не разметка приложения
Scenario: Неизвестный путь под корнем хранилища отвечает отказом
- WHEN запрос приходит на неизвестный путь под корнем хранилища
- THEN тело ответа — не разметка приложения
Scenario: Несуществующий ресурс отвечает отсутствием, а не разметкой
- WHEN браузер спрашивает под каталогом ресурсов файл, которого в сборке нет
- THEN ответ имеет код
404 - AND тело ответа — не разметка приложения
Requirement: Открытое приложение показывает вошедшего
Приложение SHALL спрашивать сервис, кто пришёл, и показывать его имя. Отказ
401 MUST показываться строкой о том, что сервис его не узнал, и MUST никуда не
уводить: своего входа у сервиса нет, а вести человека некуда — заголовок ставит
обратный прокси, и человек, которого прокси не назвал, до приложения дошёл бы
только мимо него.
Всякий иной отказ и сорванный запрос MUST показываться строкой о неудаче.
Разделять их приложение обязано: «сервис вас не узнал» и «сервис не отвечает» —
разные состояния, и человек по ним делает разное. Прежде отказ 401 уводил ко
входу; уводить стало некуда, и различие сохраняется ради текста, а не ради
перехода.
Имя пришедшего берётся ответом сервиса, а не заголовком запроса: заголовок ставит
прокси, и приложение его не видит вовсе. Имени в ответе может не быть — тогда
приложение MUST показать, что человек узнан, и MUST не подставлять вместо имени
адрес почты: его в ответе нет по норме access.
Scenario: Узнанный виден
- GIVEN запрос приложения идёт с заголовком, поставленным прокси
- WHEN он открывает приложение
- THEN приложение показывает его имя
Scenario: Неузнанному показывают, что его не узнали
- GIVEN сервис отвечает на вопрос о пришедшем кодом
401 - WHEN человек открывает приложение
- THEN приложение показывает строку о том, что его не узнали
- AND никуда его не уводит
Scenario: Отказ сервиса от неузнавания отличается
- GIVEN сервис отвечает на вопрос о пришедшем отказом, который не является неузнаванием
- WHEN человек открывает приложение
- THEN приложение показывает строку о неудаче
- AND эта строка не та, которой оно сообщает о неузнавании