Как побороть Generic User Folder, Zope user manager 29 сентября 2000 года (с вопросами и поправками обращайтесь к Дмитрию Мозжерину, dim@pharm.sunysb.edu) (использовал Zope 2.2.1, Python 1.5.2, GUF 1.2.4) ___________________________________________________________ Задача: Сделать сайт на Зопе где информация о пользователях лежит в SQLной базе данных, пользователи могут сами создавать себе аккаунт и затем входить к себе в аккаунт с титульной страницы сайта. GUF дает только самые базовые услуги для менеджмента пользователей, что как раз то, что мне нужно. Так что я скачал GUF и проборолся с ним 2 дня пока не пришел к чему-то удобоваримому. Здесь описывается упрощенный вариант результата. Я в этом примере делаю сайт с такой структурой каталогов -- login (доступен всем) users (доступен только зарегистрированным юзерам) preferences (только для юзеров) user-storage (только для юзеров) etc... (аналогично) Полезные тексты, относящиеся к GUF A)README.txt в пакете GUF Б)WALKTHROUGH.txt в пакете GUF или http://www.zope.org/Members/Zen/GenericUserFolder/walkthrough В)HOWTO "как пользовать GUF с SQL и crypt: http://www.zope.org/Members/hippy/GUF_SQL_crypt Как это делалось: 1. Скачал исходник GUF, поставил как положено вместе с другими Products (см ссылку В) 2. в корневом каталоге Зоп сделал подкаталог 'login' (пустой) в нем сделал подкаталог users (пустой) 3. в подкаталоге users сделал объект Generic User Folder, поставил аутентикацию с куками (мне так больше нравится) остальное оставил как есть. По умолчанию этот подкаталог получил идентификацию acl_users 4. опять в подкаталоге users добавил DTML method index_html, в котором добавил строчку "User: ", чтоб видеть кем я на этот документ попал. Теперь нужно проверить, что GUF работает. Как это делать написано в ссылке Б. Однако я сделал как там, попробовал зайти как jorge с паролем secret -- не получилось. Сделал по-своему: a)зашел в подкаталог users, затем в Security добавил роль -- defalutrole, убрал всю наследственность доступа (unselect all 'aquire permission settings'), разрешил анониму следующее -- Access contents information, Can Login and Logout, Use Database Methods. То же самое сделал доступным для defaultuser плюс разрешил ему View (что важно) Больше ничего в sequrity не менял. В результате каталог user и все что ниже анониму недоступно (нет доступа к View) и нужно логиниться как юзер с ролью defaltuser Замечание -- GUF напрямую нигде не вызывается. Если аноним имеет доступ к ресурсу -- никакой аутентификации не произойдет. Ресурс должен быть закрыт для анонима -- только в этом случае GUF начнет работать. б) закрыл все окошки навигатора, чтобы обнулить все пароли. Потом снова запустил нетскейп, зашел по адресу http://localhost:8080/login/users Поскольку этот каталог теперь для анонима закрыт, грузится GUF, который в свою очередь грузит страницу docLogin из GUF подкаталога acl_users. в)набираю jorge, с паролем secret -- попадаю на созданный в users индекс, где есть строчка -- User: jorge. Ладно, с этим вроде справился. Теперь надо базу данных ставить. Установка базы данных описана в ссылке (В) достаточно подробно. В моем случае база данных будет gadfly для простоты изложения, и я не буду использовать crypt. 5. Установка соединения с базой данных Сначала нужно сделать соединение с gadfly. Для этого я зашел в /login/user/acl_users, установил объект Z Gadfly Database Connection. В нем выбрал базу данных demo. При желании можно сделать и отдельную базу данных -- для этого в каталоге дистрибутива zope надо найти каталог ./var/gadfly и сделать в нем подкаталог с подходящим именем. 6.Затем я сделал таблицу 'users', для чего в объекте Gadfly_database_connection в разделе Test я набрал следующий SQL запрос: create table users (username varchar(20), password varchar(20)) в разделе Browse проверил наличие таблицы 'users'. Для простоты я не буду в данном примере возиться с ролями и обойдусь тем, что имеется по умолчанию -- ролью defaultrole. Так что с таблицами на этом покончено. 6.Теперь в acl_users надо добавить SQL-методы: __________ sql_addUser (аргументы 'username password') insert into users values (,) теперь можно попробовать этот метод чтоб создать пользователя, к примеру -- vova с паролем secret. ___________ sql_getUser (аргумент username) select password as real_password from users where username= __________ sql_getUserList (без аргументов) select username from users Все, пока хватит. 7. Изменение DTML методов в каталоге acl_users а)userList изменить на теперь раздел UserList каталога acl_users должен показывать пользователей из базы данных. В моем случае это 'vova'. Если проверить этих пользователей, они все будут иметь роль defaultrole. б) userAuthenticate должен содержать следующее: в результате чего происходит сверка имени юзера и пароля. Если все правильно, возвращается 1, если нет, возвращается 0. 8. Теперь можно проверить как все работает. Закрываем все окошки с нетскейпом, запускаем его по-новой, идем на http://localhost:8080/login/users Снова появляется окошко с приглашением ввести имя и пароль. Я ввел vova и secret, в резульате открывается index_html со строкой User: vova Теперь давайте посмотрим как это все работает. Вы набираете URL каталога, который мы закрыли от Анонимного пользователя. В результате пробуждается GenericUserFolder.py и запускает docLogin. Этот файл содержит форму
loginSuccessURL -- это переменная из GenericUserFolder.py, которая на самом деле указывает на docLoginSuccess в каталоге acl_users. Когда информация передается на сервер, DTML метод userAuthenticate исполняется автоматически. Это происходит потому, и только потому, что запрошенный URL недоступен анонимному пользователю. Прямой вызов этого метода нигде не делается, что очень смущает пока не разберешся. 9. Как сделать аутенификацию "по-нормальному" Вообще пользователи не должны долбиться в закрытые каталоги напрямую. Гораздо лучше, если есть страничка "привратник" с помощью которой пользователь может ввести имя и пароль, после чего он автоматически направляется туда куда вам хочется. Это делается следующим образом. Я добавил DTML method index_html в каталог login. Затем скопировал содержимое docLogin из каталога acl_users в DTML метод index_html каталога login Убрал строку

You will need to log in before you can continue. (что необязательно, в отличие от последующего) Заменил строку и строку на (Замечание -- в данном случае надо указывать абсолютный путь) Вот собственно и все. Теперь если во вновь открытом навигаторе набрать localhost:8080/login появится приглашение для ввода имени и пароля, после введения верного имени и пароля происходит авторизация и пользователь попадает в каталог users, где открывается index_html со строкой 'User: vova' Как это работает: Мы не ставили защиту от анонимного пользователя на каталог login. Стало быть любой может попасть на index_html страницу этого каталога и заполнить имеющуюся на ней форму с именем и паролем. После этого заполненная информация отсылается на сервер и он пытается открыть файл /login/users/acl_users/docLoginSuccess. Это не срабатывает, поскольку форма была заполнена анонимом, который не имеет доступа к данному файлу. В результате загружается GUF, который проводит аутентификацию пользователя с помощью DTML userAuthentication. Если аутентификация прошла успешно, пользователь получает доступ к docLoginSuccess и оттуда перенаправляется по адресу указанному в _guf_auth_dest. Если данный пользователь имеет право видеть указанную страницу (в данном случае это index_html каталога users), появляется запрошенная информация. Если нет -- снова появляется страница с запросом имени и пароля. Вот. Теперь осталось все сделать с нормальной базой данных, приделать форму для регистрации новых пользователей, добавить несколько десятков SQL методов, каталогов, питоновских функций ... и сайт готов;)