Новости | 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[] } ####### #######Первые строчки конструктора - это вата. Не обращайте внимания. Надо удалить.