parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

и вот что вышло

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