-
Notifications
You must be signed in to change notification settings - Fork 4
USERS Module
In order to use USERS module, you need to have a MySQL database and the following tables in it:
-- ----------------------------------------------------------------------------
-- User tables
-- ----------------------------------------------------------------------------
-- users
create table users (
id integer auto_increment primary key,
login char(30) character set utf8 not null,
email char(120) character set utf8,
name char(60) character set utf8,
passwd1 char(30) not null,
passwd2 char(30) not null,
about char(250) character set utf8,
status tinyint not null, -- 0 = created, 1 = mail sent, 2 = mail confirmed, 3 = locked, 4 = pswd reset link sent
created datetime not null,
last_login datetime,
visits integer not null,
settings integer not null,
ula_time datetime, -- unsuccessful login attempt time
ula_cnt integer not null, -- and count
deleted char(1) not null -- 'Y' / 'N'
);
create index users_login on users (login);
create index users_email on users (email);
-- user settings
create table users_settings (
user_id integer,
us_key char(15),
us_val char(60) character set utf8,
primary key (user_id, us_key)
);
-- user logins
create table users_logins (
ip char(15),
uagent char(120),
sesid char(15),
user_id integer not null,
created datetime not null,
last_used datetime not null,
primary key (ip, uagent, sesid)
);
-- password resets
create table users_p_resets (
user_id integer,
linkkey char(30),
created datetime not null,
primary key (user_id, linkkey)
);
-- messages
create table users_messages (
user_id integer,
msg_id integer,
email char(120) character set utf8,
message text character set utf8 not null default '', -- 64 kB limit
created datetime not null,
primary key (user_id, msg_id)
);Then of course, both DBMYSQL and USERS compilation switches must be present. Also, you need to add silgy_usr.c to compilation, so your m script would look like this:
#!/bin/sh
g++ silgy_app.cpp silgy_eng.c silgy_lib.c silgy_usr.c -D DBMYSQL -D USERS -o $SILGYDIR/bin/silgy_app_devThis is sample app_process_req():
int app_process_req(int ci)
{
int ret=OK;
if ( REQ("login") ) /* display Log In page */
{ /* form action="do_login" */
if ( LOGGED )
show_dashboard(ci);
else
gen_page_login(ci);
}
else if ( REQ("do_login") ) /* explicit login */
{
ret = libusr_do_login(ci);
if ( ret == OK )
{
show_dashboard(ci);
}
else if ( ret != ERR_INT_SERVER_ERROR && ret != ERR_SERVER_TOOBUSY )
{
RES_LOCATION("login?msg=%d", ret);
}
}
else if ( REQ("create_acc") ) /* display Create Account page */
{ /* form action="do_create_acc" */
gen_page_create_acc(ci);
}
else if ( REQ("do_create_acc") )
{
ret = libusr_do_create_acc(ci);
if ( ret == OK ) /* go to login page with Welcome message */
{
after_create_acc(ci);
RES_LOCATION("login?msg=%d", MSG_WELCOME);
}
else if ( ret != ERR_INT_SERVER_ERROR && ret != ERR_SERVER_TOOBUSY )
{
RES_LOCATION("create_acc?msg=%d", ret);
}
}
else if ( REQ("contact") ) /* Contact */
{ /* form action="do_contact" */
gen_page_contact(ci);
}
else if ( REQ("do_contact") )
{
ret = libusr_do_contact(ci);
if ( ret == OK )
{
RES_LOCATION("contact?msg=%d", MSG_MESSAGE_SENT);
}
else if ( ret != ERR_INT_SERVER_ERROR && ret != ERR_SERVER_TOOBUSY )
{
RES_LOCATION("contact?msg=%d", ret);
}
}
else if ( REQ("myacc") ) /* My Account */
{ /* form action="save_myacc" */
gen_page_myacc(ci);
}
else if ( REQ("save_myacc") ) /* save user profile */
{
ret = libusr_do_save_myacc(ci);
if ( ret == OK )
{
RES_LOCATION("myacc?msg=%d", MSG_CHANGES_SAVED);
}
else if ( ret == MSG_ACCOUNT_DELETED )
{
RES_LOCATION("farewell");
}
else if ( ret != ERR_INT_SERVER_ERROR && ret != ERR_SERVER_TOOBUSY )
{
RES_LOCATION("myacc?msg=%d", ret);
}
}
else if ( REQ("logout") )
{
libusr_log_out(ci);
RES_LOCATION("login?msg=%d", MSG_USER_LOGGED_OUT);
}
else if ( REQ("forgot") ) /* display forgot password page */
{ /* form action="do_forgot" */
gen_page_forgot(ci);
}
else if ( REQ("do_forgot") )
{
ret = libusr_do_send_passwd_reset_email(ci);
if ( ret == OK )
{
RES_LOCATION("forgot?msg=%d", MSG_REQUEST_SENT);
}
else if ( ret != ERR_INT_SERVER_ERROR && ret != ERR_SERVER_TOOBUSY )
{
RES_LOCATION("forgot?msg=%d", ret);
}
}
else if ( REQ("preset") ) /* display password reset page */
{ /* form action="do_preset" */
gen_page_preset(ci);
}
else if ( REQ("do_preset") )
{
ret = libusr_do_passwd_reset(ci);
if ( ret == OK )
{
RES_LOCATION("login?msg=%d", MSG_PASSWORD_CHANGED);
}
else if ( ret != ERR_INT_SERVER_ERROR && ret != ERR_SERVER_TOOBUSY )
{
RES_LOCATION("preset?msg=%d", ret);
}
}
else if ( REQ("farewell") ) /* show farewell page */
{
gen_page_msg(ci, MSG_ACCOUNT_DELETED);
}
else if ( REQ("") )
{
gen_page_main(ci);
}
else
ret = ERR_NOT_FOUND;
return ret;
}Successful libusr_do_login() call will add new record to users_logins and ls cookie to the response.
Adding keep=on to the login request will set ls cookie expiration to date to +30 days. Therefore — until you call libusr_log_out() — every subsequent request with valid ls cookie and the same User Agent as in the initial request, will automatically mark session as "logged in". Note that libusr_log_out() removes all records that belong to the user so it will log them out from every device.
Without keep=on cookie does not have expiration time, so by default it will expire by the end of the current browser session.
Logged in sessions are cached for 30 minutes after last activity. Within this range there is no need to query users_logins table.
Unsuccessful login count and time is stored in users.ula_cnt and users.ula_time. User can try 3 times without negative consequences. Then, to prevent brute-force attacks, the fourth attempt requires waiting for 1 minute, fifth — for 10 minutes, sixth — for 1 hour.