| Новости | FAQ | Авторы | Документация | В действии | Библиотека |
| Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
yes 12.03.2004 16:34 / 12.03.2004 16:36
Вобщем тут не фсяких фишек типа групп и прав (на самом деле это решается добавлением пары столбцов в бд). Оставил только то, что мне может пригодиться. Выложу, может кому-то понадобится. Там могут быть всякие неточности, но вроде работает. Или может быть что-то не доделано. Вот код:@CLASS
auth
#######
## Конструктор класса
##
## Параметры, передоваемые конструктору:
## 1. $logon_data_hash - хеш с необходимыми для авторизации данными (обычно $form:fields)
## ключи (по-умолчанию) хеша $logon_data_hash с которыми работает класс:
## - $.u (имя пользователя)
## - $.p (пароль)
## - $.logout (флаг, означающий желание юзера отлогинеться (должен def))
## эти ключи можно переобределить в хеше опций (см. ниже)
## 2. $cookie_data_hash - хеш с куками пользователя (обычно $cookies:CLASS (ой! это ведь не хеш!))
##
##
##
## 3. $db_connect_string - строка подключения к БД
## 4. $options - хеш с опциями
## доступно:
## - $.cookie_expires (сколько дней храним куки. 0 - сессионные куки (по-умолчанию))
## - $.db_expires
## - $.auth_type (По какому параметру производим идентификацию пользователя)
## Возможные значения:
## - user_name (по имени пользователя (по-умолчанию))
## - email (по мылу пользователя)
## - $.passwd_field (ключ хеша $logon_data_hash, содержащий пароль)
## - $.user_name_field (ключ хеша $logon_data_hash, содержащий имя пользователя)
## - $.email_field (ключ хеша $logon_data_hash, содержащий e-mail пользователя)
## - $.logout_field (ключ хеша $logon_data_hash, который является флагом логаута)
## - $.remindme_field (ключ хеша $logon_data_hash, который является флагом "запомнить")
##
##
#######
@create[logon_data_hash;cookie_data_hash;db_connect_string;ioptions][logout_user;auth_field;auth_value]
# Класс работает только при включенных cookies, иначе при создании объекта класса auth получаем ошибку.
#$cookie:available[yes]
#^if($cookie:available ne "yes"){^throw[cookies;^$cookie:available;Cookie files are not available. ^$cookie:available must return "yes".]}
# Текущие дата и время
$now[^date::now[]]
# Опции по-умолчанию
$options[^hash::create[$ioptions]]
^if(!def $options.cookie_expires){$options.cookie_expires[0]}
^if(!def $options.db_expires){$options.db_expires[1]}
^if(!def $options.auth_type){$options.auth_type[user_name]}
# Определение ключей хеша $logon_data_hash с которыми будет работать класс
$logon_data_fields[^hash::create[]]
$logon_data_fields[
$.passwd[p]
$.user_name[u]
$.email[m]
$.logout[logout]
$.remindme[remindme]
]
^if(def $options.passwd_field){$logon_data_fields.passwd[$options.passwd_field]}
^if(def $options.user_name_field){$logon_data_fields.user_name[$options.user_name_field]}
^if(def $options.logout_field){$logon_data_fields.logout[$options.logout_field]}
^if(def $options.email_field){$logon_data_fields.email[$options.email_field]}
# Данные, необходимые для logon/logout
$logon_data[^hash::create[$logon_data_hash]]
$logon_data[
$.passwd[$logon_data.[$logon_data_fields.passwd]]
$.user_name[$logon_data.[$logon_data_fields.user_name]]
$.email[$logon_data.[$logon_data_fields.email]]
$.logout[$logon_data.[$logon_data_fields.logout]]
$.remindme[$logon_data.[$logon_data_fields.remindme]]
]
# А это пришло из куков
$cookie_data[$cookie_data_hash]
# Определение $expires для куков
^switch(^options.cookie_expires.int(0)){
^case(0){$cookie_expires[session]}
^case[DEFAULT]{$cookie_expires[$options.cookie_expires]}
}
# Определение $db_connect_string - cтроки подключения к БД
$self.db_connect_string[$db_connect_string]
# Определяем поля, по которым происходит логон
^switch[$options.auth_type]{
^case[email]{^if(def $logon_data.email){$auth_field[email] $auth_value[$logon_data.email]}}
^case[DEFAULT]{$auth_field[name] $auth_value[$logon_data.user_name]}
}
# Таблица сессий из БД
^connect[$db_connect_string]{
$db_sessions[^table::sql{
SELECT
id, sid, created, updated, ip, user_name
FROM
auth_sessions
}]
}
# Смотрим, залогинен ли пользователь и от этого уже пляшим
^if(^is_logon[] == 1){
^logout[]
^update[]
}{
^logon[$auth_field;$auth_value]
}
# Хеш с ошибками
$errors[^hash::create[]]
# Чтобы броузер не кэшировал
$response:expires[Fri, 23 Mar 2001 09:32:23 GMT]
$response:cache-control[no-cache, must-revalidate]
$response:pragma[no-cache]
#######
#######
#######
## Залогиним юзера
#######
@logon[a_field;a_value][user;sid]
^connect[$db_connect_string]{
$user[^table::sql{
SELECT
name, email, passwd
FROM
auth_users
WHERE
$a_field = '$a_value'
}[$.limit(1)]]
}
$user[$user.fields]
^if(def $user.name && def $user.email && def $user.passwd && def $logon_data.passwd && ^math:crypt[$logon_data.passwd;$user.passwd] eq "$user.passwd"){
$sid[^math:md5[$env:REMOTE_ADDR ^now.sql-string[] ^math:random(10000)]]
$cookie:auth_sid[
$.value[$sid]
$.expires[$cookie_expires]
]
^connect[$db_connect_string]{
^void:sql{delete from auth_sessions where user_name='$user.name'}
^void:sql{insert into auth_sessions
(sid, created, updated, ip, user_name)
values
('$sid', '^now.sql-string[]', '^now.sql-string[]', '$env:REMOTE_ADDR', '$user.name')
}
$caller.db_sessions[^table::sql{
SELECT
id, sid, created, updated, ip, user_name
FROM
auth_sessions
}]
}
}
#######
#######
#######
## Обновляем дату последнего логона
#######
@update[][user]
$user[^user_info[]]
^connect[$db_connect_string]{
$user[^table::sql{
SELECT
name, email, passwd
FROM
auth_users
WHERE
name = '$user.name'
}[$.limit(1)]]
}
$user[$user.fields]
^if(def $user && ^is_logon[] == 1){
^connect[$db_connect_string]{
^void:sql{update auth_sessions set updated='^now.sql-string[]' where user_name='$user.name'}
$caller.db_sessions[^table::sql{
SELECT
id, sid, created, updated, ip, user_name
FROM
auth_sessions
}]
}
}
#######
#######
#######
## Отлогиним пользователя
#######
@logout[user_name][user]
^if(def $user_name){
^connect[$db_connect_string]{
^void:sql{delete from auth_sessions where user_name='$user_name'}
}
}{
^if(def $logon_data.logout && ^is_logon[] == 1){
^connect[$db_connect_string]{
$user[^user_info[]]
^void:sql{delete from auth_sessions where user_name='$user.name'}
^rem{### Здесь надо обновить уже подгруженную таблицу сессий ###}
$caller.db_sessions[^table::sql{
SELECT
id, sid, created, updated, ip, user_name
FROM
auth_sessions
}]
}
$cookie:auth_sid[]
^if(def $logon_data.remindme){
$cookie:auth_login[
$.value[$user.name]
$.expires[7]
]
}{
$cookie:auth_login[]
}
}
}
#######
#######
#######
## Залогинен ли текущий пользователь или пользователь с нужным именем
#######
@is_logon[user_name][user;created]
^if(def $user_name){
# Смотрим юзера с указанным именем в таблице сессий
^connect[$db_connect_string]{
$user[^string::sql{SELECT name FROM auth_users WHERE name='$user_name'}[$.limit(1)]]
}
^if(def $user && ^db_sessions.locate[user_name;$user_name]){$result(1)}{$result(0)}
}{
# Смотрим текущего посетителя
^if(def $cookie_data.auth_sid){
^if(^db_sessions.locate[sid;$cookie_data.auth_sid]){
$created[^date::create[$db_sessions.created]]
^if($created > $now-1/24*$options.db_expires){
$result(1)
}{
$result(0)
}
}{
$result(0)
}
}{
$result(0)
}
}
#######
#######
#######
## Информация о пользователе по его имени или о текущем пользователе в виде хеша
#######
@user_info[user_name]
^connect[$db_connect_string]{
$result[^table::sql{
SELECT
id, name, email, passwd, rights
FROM
auth_users
WHERE
name='^if(def $user_name){$user_name}{^if(^is_logon[] == 1){$db_sessions.user_name}}'
}[$.limit(1)]]
$result[$result.fields]
}
^if(!def $result){$result[^hash::create[]]}
#######
#######
#######
## XML код формы ввода данных
#######
@logon_form_xml[][$name]
# Выясняем, по какому полю будет происходить авторизация
^if(def $options.auth_type){
^switch[$options.auth_type]{
^case[email]{$name[$logon_data_fields.email]}
^case[DEFAULT]{$name[$logon_data_fields.user_name]}
}
}{
$name[$logon_data_fields.user_name]
}
^untaint[xml]{
<logon_form method="post">
<field type="text" name="$name" ^if(def $cookie_data.auth_login){value="$cookie_data.auth_login"} />
<field type="password" name="$logon_data_fields.passwd" />
<field type="submit" name="logon" />
</logon_form>
}
#######
#######
#######
## XML код формы логаута
#######
@logout_form_xml[][user]
^if(^is_logon[] == 1){
$user[^user_info[]]
^untaint[xml]{
<logout_form method="post">
<field type="submit" name="$logon_data_fields.logout" description="$user.name" />
<field type="checkbox" name="$logon_data_fields.remindme" selected="selected" />
</logout_form>
}
}
#######
#######
#######
## Вставляет нужную форму, в зависимости от текущего состояния.
## Имеет параметр mode, доступные значения:
## - both (показывать форму логина вместе с формой логаута)
##
#######
@form_switch[mode]
^if(^is_logon[] == 1){
^logout_form_xml[]
^if(def $mode && $mode eq "both"){^logon_form_xml[]}
}{
^logon_form_xml[]
}
#######
#######Первые строчки конструктора - это вата. Не обращайте внимания. Надо удалить.