Перейти к содержанию

Рекомендуемые сообщения

Опубликовано

Есть идея - написание бесплатной биллинговой системы, которая могла бы составить конкуренцию коммерческим собратьям,

сертификация этой системы.

Чего в этом интересного?

1. создание бесплатной КАЧЕСТВЕННОЙ альтернативы дешевым и не

-- качественным системам.

2. возможность, в последствии, на этом заработать... если конечно

-- что-то хорошее из этого получится.

3. можно будет еще что-нибудь написать, если вместе работать

-- понравится.

Почему сам не напишу?

1. собственной фантазии не хватает

2. проблемы с организацией работ (пишу пару дней, после, думаю,

-- что вообще изначально не правильно все придумал, киляю все и

-- пишу опять)

Опубликовано

Сертификация, насколько я знаю, не бесплатна Sad

Идею поддерживаю, могу предоставить свои наработки. Сейчас как раз пишу под себя биллинг. Заточен под ВПН. Могу привести список того, что он умеет сейчас и что будет уметь через два-три дня Smile

Опубликовано

Сертификация не бесплатна, но если получится хорошая вещь то,

даже сделав эту вещь бесплатной, можно заработать на ней денег и

как минимум, окупить сертификацию и пиво Smile

Приводи Smile Интересно посмотреть Smile Только я вот хочу сделать

что-нибудь без привязок т.е., чтобы привязка была не

обязательной... т.е., представлять подключеник к vpn, к примеру,

как один из параметров услуги "передача трафика", как это сделано

в той же UTM.

Опубликовано

Пиво? Кто сказал ПИВО?? Smile

ААА реализуется на радиусе, в моем случае - rlm_perl. Пока учет ведется тем же перловым скриптом, что и две другие АА Smile, но хочу вынести в отдельный демон.

Алгоритм таков:

1. Авторизация

Клиент поднимает pptp-соединение. PPPD через radius.so обращается к радиусу. Вызывается функция authorize, которая при удачной авторизации отдает NAS'у ИП для ВПН-соединения, маску, помещает в RAD_CHECK плэйнтекстовый пароль пользователя. После этого вызывается радиусовский модуль mschap, который хэширует пароль в MD4 (или что там в MSCHAP используется) и отдает хэш NAS'у.

2. Аутентификация

Тут используется только модуль MSCHAP, который проверяет хэши и по результатам впускает пользователя.

3. Аккаунтинг

Это должно реализоваться отдельным демоном, не зависящим от радиусовского Interim-Update-Interval, но сейчас работает в том же перловом скрипте.

Сведенья о тарифах хранятся в трех SQL-таблицах - tar_base, tar_time, tar_traf.

В первой - базовые ставки за вход/исх трафик и время и потолок трафика для данного тарифа (для предопл. трафика)

Во второй - почасовые множители для трафика и времени.

В третьей - множители для трафика по направлениям/портам.

Т.о. сумма, ежеминутно снимаемая с пользовательского счета, определяется как:

my $minus = $time * $row->{'hour'} * $row->{'hmul'} +

$inb * $row->{'inb'} * $row->{'inbmul'} / MB +

$outb * $row->{'outb'} * $row->{'outbmul'} / MB;

Здесь

$time - интервал тарифицируемого времени

$inb - вход. трафик

$outb - исход. трафик

$row->{'hour'} - базовая ставка за час

$row->{'inb'} - базовая ставка за метр вход.

$row->{'outb'} - базовая ставка за метр исх.

$row->{'hmul'} - временной множитель для данного тарифа

$row->{'inbmul'} - вход. траф. множитель для данного тарифа

$row->{'outbmul'} - исх. траф. множитель для данного тарифа

Тут не учитываются хосты и порты, при их введении нужно дополнить формулу. Правда, с т.з. производительности это нужно делать именно в отдельном демоне, причем только с агрегированным трафиком, иначе биллинг захлебнется:)

Опубликовано

Интересная тема Smile Надо будет почитать Smile

Сейчас разбираюсь с модульностью в своей реализации и возникла вот такая проблема:

есть некая таблица `user` и некая таблица `account`

процесс заведения пользователя состоит из звух частей:

1. занесение записи в таблицу `user`

2. занесение записи в таблицу `account`

INSERT INTO `user` ( `name`, `address`, `telephone` ) VALEUS ( '$username', '$address', '$telephone' );

INSERT INTO `user` ( `uid`, `login`, `password` ) VALUES ( '$uid', '#login', $password );

При этом, в таблице `user` есть поле

`id` INT AUTO_INCREMENT

и соответственно, во второи INSERT в базу, поле `uid`, должно

соответствовать инкрементному полю `id` для первого INSERT.

В данной ситуации, можно воспользоваться LAST_INCREMENT_ID, но

тогда, мы получаем последнюю инкрементную величину, при этом,

не зависимо от того, в какую таблицу была вставлена запись, а

в этот момент, так же, ведется запись трафика в базу (при помощи

того же ulogd).

вот и сижу, не понимаю... как быть...

CREATE TABLE `pandora_user` (
  `id`            INT   AUTO_INCREMENT        COMMENT 'Уникальный идентификатор пользователя',
  `name`          TEXT  NOT NULL  DEFAULT ''  COMMENT 'Полное имя пользователя',
  `address`       TEXT  NOT NULL  DEFAULT ''  COMMENT 'Адрес проживания',
  `telephone`     TEXT  NOT NULL  DEFAULT ''  COMMENT 'Контактный телефон',
  `email`         TEXT  NOT NULL  DEFAULT ''  COMMENT 'Адрес эллектронной почты',
  `pasport_get`   TEXT  NOT NULL  DEFAULT ''  COMMENT 'Кем выдан пасспорт',
  `pasport_num`   TEXT  NOT NULL  DEFAULT ''  COMMENT 'Серия и номер паспорта',
  
  PRIMARY KEY (`id`)
) ENGINE = MYISAM;

CREATE TABLE `pandora_account` (
  `id`            INT   AUTO_INCREMENT        COMMENT 'Уникальный идентификатор аккаунта',
  `uid`           INT   NOT NULL  DEFAULT '0' COMMENT 'Ссылка на пользователя',
  `login`         TEXT  NOT NULL  DEFAULT ''  COMMENT 'Логин',
  `group`         TEXT  NOT NULL  DEFAULT ''  COMMENT 'Группа',
  `password`      TEXT  NOT NULL  DEFAULT ''  COMMENT 'Пароль',
  
  PRIMARY KEY (`id`)
) ENGINE = MYISAM;

Делать это в однойтаблице тоже крайне не хочется так, как

хочется реализовать вариант, когда у одного пользоваетеля, может

быть несколько различных логинов.

Опубликовано

Наверное, все-таки

Цитата:

INSERT INTO `user` ( `name`, `address`, `telephone` ) VALEUS ( '$username', '$address', '$telephone' );

INSERT INTO `account` ( `uid`, `login`, `password` ) VALUES ( '$uid', '#login', $password );

При этом, в таблице `user` есть поле

`id` INT AUTO_INCREMENT

и соответственно, во второи INSERT в базу, поле `uid`, должно

соответствовать инкрементному полю `id` для первого INSERT.

В данной ситуации, можно воспользоваться LAST_INCREMENT_ID, но

тогда, мы получаем последнюю инкрементную величину, при этом,

не зависимо от того, в какую таблицу была вставлена запись, а

в этот момент, так же, ведется запись трафика в базу

Попробуй так:

CREATE TRIGGER test AFTER INSERT ON user FOR EACH ROW INSERT INTO account ( `uid`, `login`, `password` ) VALUES ( NEW.id, '#login', $password );

Опубликовано

Да, это интересное решение. Есть только одно "но":

поледовательность должно быть примерно следующая:

СРЕАТЕ ТАБЛЕ `user` ( ... );
CREATE TABLE `account` ( ... );
CREATE TRIGGER `account` AFTER INSERT ON `user` FOR EACH ROW \
  INSERT INTO `account` ( `uid` ... ) VALUES ( NEW.id, ... );

INSERT INTO `user` ( ... ) VALUES ( ... );

... и при этом, автоматически выполняется вставка зависи в

`account`, а чего вставляется? ведь вставляться должна информация

которая так же получена из скрипта...

Решение: перед инсертом в `user` делать что-то вроде:

SET @myLogin := '$login';
...
SET @myPassword := '$pasword';

и тогда можно делать INSERT в `user`... но еще одно "но", все же,

остается... у меня мания на "гибкость" самописных приложений...

при таком подходе, становится невозможным записать в базу инфу о

пользователе, не создав для него аккаунт.

Интересен был бы вариант запроса, который или в который

инкапсулировался бы INSERT в `user` и после выполнения, возвращал

бы значение инкрементного поля.

Пробывал наворотить SELECT'ов в одном запросе, но ничего

хорошего из этого не получается... не клеются они у меня так,

как надо.

Напрашивеется вариант с кучей тупобональных селектов после записи

но это крайне не красивое, не интересное и думаю, в перспективе,

многожрущее решение, которое, так же еще и не верно так, как

в базе (это конечно крайне мало вероятно, но всеже), существует

вероятность одновременного существования разных людей, но с

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

они раньше не фиксировались, будут собираться очень долго,

найти двух-трех людей с одинаковыми именами, работающих в одном

здании и у которых один и тот же контактный рабочий телефон - не

так уж и сложно) (ЗЫ: у нас в офисе, три Николая и два с

половиной Андрея... благо хоть все остальные данные разные).

Опубликовано

Ну... кажется, практически придумал решение:

CREATE TRIGGER myTrigger AFTER INSERT ON `user` FOR EACH ROW \
  SET @lastId := NEW.id;
INSERT INTO `user` ...;
INSERT INTO `account` ( `uid`, ...) VALUES ( @lastId, ... );
DROP TRIGGER `user`;

Единственное, что мне тут не нравится, у меня не получилось создать больше одного триггера на таблицу и создавать/удалять триггер, приходится при каждом таком запросе.

Может есть более изящный вариант? Smile

Опубликовано

Блииин... вот засада...

минут десять не мог понять, где же гадость залегла...

пытаюсь создать юзверя:

CREATE TRIGGER myTrigger AFTER INSERT ON `pandora_user` FOR EACH ROW SET @myUid := NEW.id;
INSERT INTO `pandora_user` ( `name`, `address`, `telephone`, `email`, `pasport_get`, `pasport_num` )
VALUES ( '123', '234', '345', '', '', '' );
INSERT INTO `pandora_account` ( `uid`, `login`, `group`, `password` )
VALUES ( @myUid, '123', 'Пользователь', '123' );
DROP TRIGGER myTrigger

Не проходит... точнее, из скрипта не проходит... в базе, от имени

root, проходит... дооолго думал... селекты из скрипта делаются, а

запись - нет...

Захожу в базу как скриптоюзверь и повторяю запрос на запись - фиг

вам - национальная индейская изба... а запарка на моменте

создания триггера - "ERROR 1227 (42000): Access denied; you need

the SUPER privilege for this operation" :(

Цитата:

18.1. CREATE TRIGGER Syntax

CREATE

[DEFINER = { user | CURRENT_USER }]

TRIGGER trigger_name trigger_time trigger_event

ON tbl_name FOR EACH ROW trigger_stmt

This statement creates a new trigger. A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. CREATE TRIGGER was added in MySQL 5.0.2. Currently, its use requires the SUPER privilege.

Опубликовано

В принципе, решил проблему путем более внимательного рассмотра

LAST_INSERT_ID. После более подробного разбора данный функции,

стало ясно, что опасности в ее таковом использовании нет так,

как несмотря на отсутствие ее привязки к конкретной таблице,

ее значение не передается между "сессиями" т.е., подключившись

несколько раз к баде, даже под одним пользователем, эта функция,

является, своего рода, "переменной сеанса" т.е, не зависимой от

других сессий.

И так, запрос вида:

CREATE TRIGGER myTrigger AFTER INSERT ON `pandora_user` FOR EACH ROW SET @myUid := NEW.id;
INSERT INTO `pandora_user` ( `name`, `address`, `telephone`, `email`, `pasport_get`, `pasport_num` )
VALUES ( '123', '234', '345', '', '', '' );
INSERT INTO `pandora_account` ( `uid`, `login`, `group`, `password` )
VALUES ( @myUid, '123', 'Пользователь', '123' );
DROP TRIGGER myTrigger;

был успешно заменен на:

INSERT INTO `pandora_user` ( `name`, `address`, `telephone`, `email`, `pasport_get`, `pasport_num` )
VALUES ( '123', '234', '345', '', '', '' );
INSERT INTO `pandora_account` ( `uid`, `login`, `group`, `password` )
VALUES ( LAST_INSERT_ID(), '123', 'Пользователь', '123' );

Smile

Опубликовано

Блин... чего-то у меня в последнее время вопросов много...

совсем разучился думать самостоятельно... на пенсию пора...

или как минимум, на отдых...

Вопрос следующего плана: есть у меня ряд запросов типа INSERT...

к примеру, допустим, наверное, три :)

my $queru = "INSERT ...; INSERT ...; INSERT ...;";
my $sth = $dbh -> prepare ( "$sql" ); $sth -> execute;

Не выполняется :(

my $queru = "INSERT ...";
my $sth = $dbh -> prepare ( "$sql" );
$sth -> execute;
my $queru = "INSERT ...";
my $sth = $dbh -> prepare ( "$sql" );
$sth -> execute;
my $queru = "INSERT ...";
my $sth = $dbh -> prepare ( "$sql" );
$sth -> execute;

Выполняется :/

Не понимаю :(

Опубликовано

Ганс, зачем при каждом запросе триггер-то создавать? Это ж такой же элемент логики, как и хранимые процедуры, их создал раз при создании самой базы - и они дальше сами работают. Я, по крайней мере, не могу себе представить ситуации, в которой бы возникла необходимость создавать/изменять/удалять триггеры во время работы с базой.

Цитата:

Вопрос следующего плана: есть у меня ряд запросов типа INSERT...

к примеру, допустим, наверное, три Smile

Не выполняется Sad

И не выполнится. DBI рассчитан на атомарные операции:

# perldoc DBI

...

Some command-line SQL tools use statement terminators, like a semicolon, to indicate the end of a statement. Such terminators should not normally be used with the DBI.

...

Если хочется свести к минимуму общение с базой, можно попробовать запихнуть множественные операции в одну хранимую процедуру.

Опубликовано

Цитата:

Ганс, зачем при каждом запросе триггер-то создавать? Это ж такой же элемент логики, как и хранимые процедуры, их создал раз при создании самой базы - и они дальше сами работают. Я, по крайней мере, не могу себе представить ситуации, в которой бы возникла необходимость создавать/изменять/удалять триггеры во время работы с базой.

Все очень просто. Триггер - очень удобная штука, но... уменя

получилось создать только один триггер, на одну таблицу базы, а

это, крайне не удобно. Долго мучался с созданием второго, но так

ничего и не вышло... в документации по мускулю сказано, что если

мускуль говорит мол "триггер с таким именем уже есть" - удалите

его и будет вам счастье... на практике - опять национальная

индейская изба... при попытке удалить триггер, который уже есть,

но который никто не создавал и который мешает создать новый

триггер, мускуль говорит - "триггер с таким именем еще не создан"

Smile

Опубликовано

Цитата:

mysql> create database test; use test;

Query OK, 1 row affected (0.01 sec)

Database changed

mysql> create table a(x int);

Query OK, 0 rows affected (0.02 sec)

mysql> create table b(y int);

Query OK, 0 rows affected (0.01 sec)

mysql> create trigger t1 after insert on a for each row update b set y=new.x;

Query OK, 0 rows affected (0.00 sec)

mysql> create trigger t2 after update on a for each row update b set y=new.x;

Query OK, 0 rows affected (0.01 sec)

mysql> create trigger t3 after update on b for each row update a set x=old.y;

Query OK, 0 rows affected (0.01 sec)

mysqld Ver 5.0.26 for pc-linux-gnu on i686 (Gentoo Linux mysql-5.0.26-r1)

Опубликовано

В общем, нахожусь в велком ступоре Sad

Суть ступора в том, что не могу написать интерфейс ко всей этой

пакости...

Логика (если она есть) рассуждений:

- Есть некий программный продукт, состоящий из "ядра" и модулей.

в данном случае, "ядро" берет на себя функции "конфигурирования",

всей этой системы, управления модулями, предоставления прав на

их использование и т.д.

- Соответственно, чтобы все это нормально можно было использовать

у этого должен быть какой-то общий интерфейс. Вписывать HTML в

перловый код, как-то очень не хочется...

-- В общем... я в шаблонах и интерфейсах потерялся...

Опубликовано

Я щас прикручиваю морду к биллингу, html+php. Вообще, имхо, писать морду до более-менее полного оформления биллинга не стоит, очень много потом менять придется. Меня просто с биллингом, заточенным под мою ситуация, сроки торопят, поэтому все делается максимально быстро и соотв. не особо продумано Smile

Как запущу этот биллинг в продакшн, можно будет уже думать о теоретической части другого биллинга, большого и красивого Smile

Опубликовано
Ну вот у меня, как раз, задача - большой и красивый... но главное
- это даже не красота, а универсальность и следовательно, модуль-
ность.

Сейчас застрял на самой "концепции".
Есть несколько вариантов реализации такой системы:
1. Одним из вариантов, мне видится написание некого приложения,
   с которым будет работать пользователь, а уже это приложение,
   будет работать с модулями.
   Соответственно, это приложение должно предоставлять этим при-
   ложениям соответствующие функции, такие как:
   - работа с базой данных
   - отображение результатов работы модуля
   - и т.д.
   На этапе начала работы с этим же приложением, должна проходить
   аутентификация/авторизация пользователей, общее конфигурирова-
   ние системы и т.п.
   Проблема, с которой я столкнулся, в процессе реализации данно-
   го решения - организация и стандартизация методов общения
   основного приложения и модулей. Еще одной проблемой явилось то
   что в этом приложении, должны быть определены все имеющиеся
   модули, набор которых, может изменяться и для добавления ново-
   го модуля, не должно требоваться, пусть даже мелкое, но пере-
   писывание основного приложения/системы.
2. Вторым вариантом, является то, как построен webmin т.е., есть
   множество модулей, которые являются вполне не зависимыми друг
   от друга, а их общение с пользователем/системой, проходит
   посредством использования библиотек webmin'а. По сути, вариант
   великолепный, но он крайне усложняет использование шаблонов в
   пользовательском интерфейсе так, как за ход работы модуля,
   происходит нескольхо действий типа "стандартный_модуль(принтни
   заголовак)", "стандартный_модуль(принтни_еще_чего-нибудь)",
   стандартный_модуль(заверши_страницу). Другими словами, вывод
   пользовательского интерфейса происходит не единовременно, а
   в процессе всей работы. Так же, в ходе работы, модуль так же
   выводит информацию, не обращаясь к стандартным библиотекам
   webmin, что с одной стороны, позволяет реализовать такую вещь,
   как "интерактивность" приложения (в моем понимании, это неме-
   дленное отображение информации, к примеру, результат ping'а),
   но с другой стороны, делает унификацию пользовательского
   интерфейса, тошлько условной, оставляя правильность работы
   интерфейса исключительно на совести модуля (и дело касается
   но только таких вещей, как интерфейс... ошибка в модуле, при
   такой реализации, может поставить под угрозу, как минимум
   безопасность, а то и работоспособность всей системы, а это,
   как мне кажется, в таком программном продукте, с открытым
   кодом, просто не допустимо).

Вот и сижу я в ступоре... пока писал этот текст (овообще, всей
этой писаниной на форумах, я занимаюсь даже не для того, чтобы
получить от кого-то решение моей задачи, а чтобы мысли по поло-
чкам разложить... да и может кто идейку какую подкинет)... в
общем, пока все это писал, от второго варианта, решил действи-
тельно отказаться (до этого, я и не думал о таких его минусах).

Буду думать над первым вариантом.
По сути, основной траблой для меня, сейчас является реализация
единовременного вывода поьзовательского интерфейса.

заполнение шаблона, у меня происходит сейчас следующим образом:
sub Template {
  my %VAR = %main::VAR;
  my $template = shift;
  open ( TEMPLATE, "$template" );
  $template = join ( '', <TEMPLATE> );
  close ( TEMPLATE );
  while ( $template =~ m/\$VAR\{([0-9,A-Z,a-z,_])\}/ ) {
    for ( $template ) { s\$VAR\{([0-9,A-Z,a-z,_])\}/$VAR{$1}/eg }
  }
  return $template;
}
$VAR{MENU} = Template ( "../htdocs/tpl.menu.html" );
$VAR{MAIN} = Template ( "../htdocs/tpl.main.html" );

недостаток данного метода заключается в том... а не знаю в чем...
еще сам не понял, че мне надо... в общем, еще чего-нибудь приду-
маю, отпишусь 
Опубликовано
А вот такой, можно сказать, культурный или эстетический, или как
там еще его можно назвать, вопрос - какой код нагляднее:

for ( param ) { $export{$_} = param ($_) if param ($_) ne "" }

или

for ( param ) { if ( param ($_) ne "" ) { $export{$_} = param ($_) } }

? 
Опубликовано

Hans R. Steiner писал(а) Sun, 19 November 2006 14:45

А вот такой, можно сказать, культурный или эстетический, или как
там еще его можно назвать, вопрос - какой код нагляднее:

for ( param ) { $export{$_} = param ($_) if param ($_) ne "" }

или

for ( param ) { if ( param ($_) ne "" ) { $export{$_} = param ($_) } }

? 

В перловых доках рекомендуется первая форма, но я ее терпеть не выношу Smile Разница, как мне кажется, что и с конструкциями do {} while и while {}

Поэтому я обычно использую do_something unless something, но if something {do something} Smile

Опубликовано
Думаю, к окончанию недели, усперю выложить уже что-нибудь рабочее
но я сейчас акцентирую свое внимание все больше не на автономной
части системы т.е., не на биллинге как таковом, а на пользова-
тельском интерфейсе... с одной стороны, это не совсем верный под-
ход, но с другой, именно эта часть является для меня наиболее
проблемной и от этой проблемы, я хочу избавится в первую очередь.
Опубликовано

Долго думал, как использовать одну и ту же логику для работы с ВПНом и прямым подключением. Решил трактовать прямое как такую же сессию, как и ВПН. Время начала, окончания сессии и состояние ее определяются по факту наличия машины в сети, то есть по потенциальной возможности пользоваться инетом. Тем легче это осуществить, что от счетчиков интерфейсов отказался, приделываю netflow.

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...