#include "content.hpp" #include "user.hpp" #include "strusCms.hpp" #include "captcha.hpp" #include #include #include #include #include namespace apps { // user user::user( strusCms &cms ) : master( cms ) { cms.dispatcher( ).assign( "/login", &user::login, this ); cms.mapper( ).assign( "login" ); cms.dispatcher( ).assign( "/logout", &user::logout, this ); cms.mapper( ).assign( "logout" ); cms.dispatcher( ).assign( "/register", &user::register_user, this ); cms.mapper( ).assign( "register" ); cms.dispatcher( ).assign( "/confirm_register", &user::confirm_register, this ); cms.mapper( ).assign( "confirm_register" ); } void user::login( ) { content::user c( cms ); ini( c ); if( request( ).request_method( ) == "POST" && session( ).is_set( "prelogin" ) ) { c.login.load( context( ) ); if( c.login.validate( ) ) { session( ).reset_session( ); session( ).erase( "prelogin" ); session( )["username"] = c.login.username.value( ); session( ).expose( "username" ); response( ).set_redirect_header( cms.root( ) ); } } session( ).set( "prelogin", "" ); render( "login", c ); } void user::logout( ) { content::user c( cms ); session( ).clear( ); ini( c ); render( "logout", c ); } void user::register_user( ) { content::user c( cms ); ini( c ); if( request( ).request_method( ) == "POST" ) { c.register_user.load( context( ) ); if( c.register_user.validate( ) ) { response( ).set_redirect_header( cms.root( ) + "/confirm_register" ); } } render( "register_user", c ); } void user::confirm_register( ) { content::user c( cms ); ini( c ); if( request( ).request_method( ) == "POST" ) { c.confirm_register.load( context( ) ); if( c.confirm_register.validate( ) ) { response( ).set_redirect_header( cms.root( ) + "/login" ); } } render( "confirm_register", c ); } // TODO: make this a salted hash bool user::check_login( std::string user, std::string password ) { if( user.empty( ) || password.empty( ) ) { return false; } cppdb::session sql( cms.conn ); cppdb::result r; r = sql << "SELECT id, password FROM user WHERE username=?" << user << cppdb::row; if( r.empty( ) ) { return false; } int id; r >> id; std::string pass; r >> pass; if( password != pass ) { return false; } std::time_t now_time = std::time( 0 ); std::tm now = *std::localtime( &now_time ); cppdb::statement stmt; stmt = sql << "INSERT INTO login(user_id, last_login) VALUES(?, ?)" << id << now; stmt.exec( ); return true; } bool user::user_exists( std::string user ) { if( user.empty( ) ) { return false; } cppdb::session sql( cms.conn ); cppdb::result r; r = sql << "SELECT username FROM user WHERE username=?" << user << cppdb::row; if( r.empty( ) ) { return false; } return true; } void user::ini( content::user &c ) { master::ini( c ); struct captcha ca = generateCaptcha( ); last_captcha = new_captcha; new_captcha = ca.text; c.captcha_base64 = ca.base64; } } // namespace apps namespace content { user::user( apps::strusCms &cms ) : login( cms ), register_user( cms ), confirm_register( cms ) { } // login login_form::login_form( apps::strusCms &cms ) : cppcms::form( ), cms( cms ) { username.message( "Your login" ); username.error_message( "The login is illegal" ); password.message( "Your password" ); password.error_message( "Your password is illegal" ); submit.value( "Log in" ); add( username ); add( password ); add( submit ); username.non_empty( ); password.non_empty( ); } bool login_form::validate( ) { if( !form::validate( ) ) { booster::ptime::sleep( booster::ptime( 5, 0 ) ); return false; } if( !cms.user.check_login( username.value( ), password.value( ) ) ) { username.valid( false ); password.valid( false ); password.clear( ); booster::ptime::sleep( booster::ptime( 5, 0 ) ); return false; } return true; } // register user register_user_form::register_user_form( apps::strusCms &cms ) : cppcms::form( ), cms( cms ) { username.message( "Your login" ); username.error_message( "Your login is illegal" ); password.message( "Your password" ); password.error_message( "Your password is illegal" ); password2.message( "Your password (again)" ); password2.error_message( "Your password doesn't match" ); captcha.message( "Enter the correct captcha" ); captcha.error_message( "Captcha didn't match" ); submit.value( "Register user" ); add( username ); add( password ); add( password2 ); add( captcha ); add( submit ); username.non_empty( ); password.non_empty( ); password2.non_empty( ); captcha.non_empty( ); } bool register_user_form::validate( ) { if( !form::validate( ) ) { return false; } if( cms.user.user_exists( username.value( ) ) ) { username.valid( false ); password.valid( false ); username.error_message( "Username is taken" ); booster::ptime::sleep( booster::ptime( 5, 0 ) ); return false; } if( password.value( ).compare( password2.value( ) ) != 0 ) { password.valid( false ); password2.valid( false ); password2.error_message( "Passwords didn't match" ); booster::ptime::sleep( booster::ptime( 5, 0 ) ); return false; } if( captcha.value( ).compare( cms.user.last_captcha ) != 0 ) { captcha.valid( false ); captcha.clear( ); return false; } return true; } // confirm user registration form confirm_register_form::confirm_register_form( apps::strusCms &cms ) : cppcms::form( ), cms( cms ) { code.error_message( "The code you provided is not correct" ); submit.value( "Verify" ); add( code ); add( submit ); code.non_empty( ); } bool confirm_register_form::validate( ) { if( !form::validate( ) ) { return false; } // TODO: check code supplied against code in the DB, this is a // method in the user class //~ if( !cms.user.check_code( code.value( ) ) ) { //~ code.valid( false ); //~ booster::ptime::sleep( booster::ptime( 5, 0 ) ); //~ return false; //~ } return true; } } // namespace content