Как отменить дальнейшее выполнение через auto.p ? |
Так сложилось что хотелось по-быстрому (без классов авторизаций и прочего) разрулить парсером доступ на различные части веб-интерфейса. Хотелось использовать встроенный механизм собирать иерархию auto.p и по аналогии с .htaccess хотел заюзать это. Такая примерно структура файлов:
/auto.p
/index.html
/web_admin/auto.p
/web_admin/index.html
/web_user/auto.p
/web_user/index.html
Есть и БД, и форма логина в морде сайта и прочее, при авторизации устанавливаются свои глобальные переменные $GL_login, $GL_group, $GL_name ...
При успешном входе, пользователя редиректит в его кабинет в зависимости от его $GL_group, то есть если это admin, то в /web_admin/ как бы все ок, при выходе редиректит на главную. Если принудительно зайти в папку то исполнения кода все равно будет в контексте пользователя и ничего не исполнит, но чтобы не было никаких некрасивых сообщений я хотел, чтобы пользователь который зашел не в свой кабинет "беззвучно" редиректился на главную по инструкции в auto.p, но понял, что код все равно исполняется... дальше доконца.
не вдаваясь в динамические подробности по сути код таков:
^if($GL_group ne 'admin'){
$response:location[/]
}
то есть если зашедший в раздел /web_admin/ не имеет $GL_group='admin' то его тело ответа должно было бы переопределиться на редирект 304 или какой то там... однако код дальше исполняется в index.html этой же папки цепляя весь фарш кода для кабинета админа, но находясь в контексте другого GL_group конечно имеет 0 записей из БД и ругается уже другими модулями. А мне хотелось бы как то заюзать auto.p чтобы завернуть код накорню в другую степь и средиректить его.
P.S.: Я понимаю что могу это разруливать в index.html, но проблема в том, что *.html не одна а десяток, и дописывать какую-то обертку к каждому *.html внутри как то не кошерно. |
Весь код с авторизацией оборачиваете во что-то подобное:
^try{
весь код с авторизацией (классы/методы) и т.д.
^if($GL_group ne 'admin'){
(типов ошибок может быть сколько угодко...)
^throw[access denied;/]
}
}{
(... обработчиков тоже)
^if($exception.type eq 'access denied'){
$response:location[$exception.source]
[code]и всё что ещё захотите } }[/code] |
Это не то, про что я спросил |
Как обернуть сам код "мягко" или try-еем я и сам знаю. Мне интересен вопрос, могу ли я остановить/перенаправить действие интерпретатора именно на стадии auto.p? то есть чтобы не выполнился код написанный в вызываемом .html |
Точно также: try/catch.
Вызов main метода класса MAIN неизбежен, если до этого не вывалиться в exception. |
Просто @main прописывайте в auto.p, а в index.html только @body и пр... |
... тогда все сведется к простому:
auto.p
@main[]
^if(пользователь авторизован){
^title[]
^body[]
...
}{
$response:location[/]
}
|
всем спасибо - @main - ответ на вопрос |
Re: всем спасибо - @main + try - ответ на вопрос |
Я не сразу понял, это отличный ответ то что надо! |
При том надо кстати добавить, что так пример не работает, надо... |
@auto[]
^try{
^if($GL_group ne 'admin'){
^throw[access_denied;authform]
}
}{
}
правильно же..? |
возможны варианты: - лично я бы авторизацию вообще в @auto не помещал бы, а добавил бы метод-обёртку в @main. но это в общем ваше дело.
- не обрабатывать исключение в @auto, а делать это в @unhandled_exception (как вы сами догадались). мне такой подход не нравится, т.к. с моей точки зрения, @unhandled_exception предназначен немного не для этого.
- можно перехватывать исключение, обрабатывать, и выставлять какой-нить флаг, глядя на который @main не будет отрабатываться (ага, там добавить проверку).
- а можно при обработке исключения... перезаписывать @main (читать про ^process) на новый, который и будет показывать "403. Access Denied"
P.S. если не обрабатываете исключение, то и try не нужен :) |
Да, @auto удобмен тем, что он собирается иерархически, то есть удобно ставить авторизацию на всю папку и все что внутри. А с методом-оберткой согласен я бы тоже так сделал и сделаю в будущем, но сейчас просто надо было корректно "пропатчить" очень много наплодилось html-ек. Про переопределение @main ^process-ом это весело, но как крайний метод когда уж совсем по-другому никак. На самом деле у меня есть ключевой метод ^template и он все собирает в кучу, вот его и надо подправить К слову говоря Parser по сути нативный шаблонизатор если так посудить, по стилю того, что всё есть print, а код между html то Парсер это мощнейший шаблонизатор-язык |
по поводу переопределения @main -- я говорил серьёзно. ведь там не обязательно писать весь код, можно сделать просто:
auto.p
^try{
...
}{
^if($exception.type eq "access.denied"){
$exception.handled(true)
^process{^@main[]^#0A^^access_denied[]^#0A}
}
}
и всё. исключение перехвачено и @main[] переопределён, т.е. он не выполнится.
по моему это лучше чем в @unhandled_exception огород городить. |
Миша хорошо придумал с переопределением @main[]. В вашей ситуации скрорее всего так и стоит поступить.
В свою очередь, я бы не допускал такой запутанной структуры с кучей html и auto.p, а пошёл бы от обратного: Apache mod_rewrite -> перенаправление всех запросов к одному файлу (/index.html, например) -> а в нём уже выполнение любой структуры с подключением нужных классов.
Тогда весь @main[] в index.html можно обёрнуть в try/catch с перехватом ошибок и флагом handled(true) (запыл про него написать в первом сообщении). |