diff options
Diffstat (limited to 'src/user.cpp')
-rw-r--r-- | src/user.cpp | 118 |
1 files changed, 105 insertions, 13 deletions
diff --git a/src/user.cpp b/src/user.cpp index 5b53416..3541eba 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -2,6 +2,7 @@ #include "user.hpp" #include "strusCms.hpp" #include "captcha.hpp" +#include "sha1.hpp" #include <cppcms/url_dispatcher.h> #include <cppcms/url_mapper.h> @@ -9,6 +10,10 @@ #include <cppcms/session_interface.h> #include <booster/posix_time.h> +#include <cstdlib> +#include <sstream> +#include <iomanip> + namespace apps { // user @@ -63,9 +68,29 @@ void user::register_user( ) if( request( ).request_method( ) == "POST" ) { c.register_user.load( context( ) ); if( c.register_user.validate( ) ) { - response( ).set_redirect_header( cms.root( ) + "/confirm_register" ); + std::string code = registration_start( c.register_user.username.value( ), + c.register_user.password.value( ), c.register_user.email.value( ) ); + + cms.mail.subject = "Registration request"; + + std::ostringstream oss; + oss << "Your registration code is: " << code << "\n"; + + cms.mail.body = oss.str( ); + cms.mail.to = c.register_user.email.value( ); + cms.mail.send( ); + if( cms.mail.hasError( ) ) { + c.register_user.email.valid( false ); + c.register_user.email.error_message( "Can't send email to this address" ); + booster::ptime::sleep( booster::ptime( 5, 0 ) ); + delete_user( c.register_user.username.value( ) ); + std::cerr << "SEND MAIL ERROR: " << cms.mail.getLastError( ) << std::endl; + } else { + response( ).set_redirect_header( cms.root( ) + "/confirm_register" ); + } } } + render( "register_user", c ); } @@ -76,14 +101,20 @@ void user::confirm_register( ) if( request( ).request_method( ) == "POST" ) { c.confirm_register.load( context( ) ); if( c.confirm_register.validate( ) ) { - response( ).set_redirect_header( cms.root( ) + "/login" ); + if( cms.user.verify_registration_code( c.confirm_register.code.value( ) ) ) { + response( ).set_redirect_header( cms.root( ) + "/login" ); + } else { + booster::ptime::sleep( booster::ptime( 5, 0 ) ); + c.confirm_register.code.valid( false ); + } } } + render( "confirm_register", c ); } // TODO: make this a salted hash -bool user::check_login( std::string user, std::string password ) +bool user::check_login( const std::string user, const std::string password ) { if( user.empty( ) || password.empty( ) ) { return false; @@ -116,7 +147,7 @@ bool user::check_login( std::string user, std::string password ) return true; } -bool user::user_exists( std::string user ) +bool user::user_exists( const std::string user ) { if( user.empty( ) ) { return false; @@ -132,6 +163,75 @@ bool user::user_exists( std::string user ) return true; } +namespace { + +std::string generate_token( ) +{ + char chars[] = "ABCDEF1234567890"; + std::string token; + + for( int i = 0; i < 12; i++ ) { + token += chars[rand( ) % 16]; + } + + return token; +} + +std::string compute_token_hash( const std::string user, const std::string token ) +{ + sha::SHA1 sha; + unsigned int res[5]; + sha.Reset( ); + sha << user.c_str( ) << token.c_str( ); + + std::ostringstream oss; + for( int i = 0; i < 5; i++ ) { + oss << std::uppercase << std::hex << std::setw( 8 ) << std::setfill( '0' ) << res[i]; + if( i < 4 ) oss << ' '; + } + + return oss.str( ); +} + +} + +std::string user::registration_start( const std::string user, const std::string password, const std::string email ) +{ + std::time_t now_time = std::time( 0 ); + std::tm now = *std::localtime( &now_time ); + std::string token = generate_token( ); + std::string code = compute_token_hash( user, token ); + + cppdb::session sql( cms.conn ); + cppdb::statement stmt; + stmt = sql << "INSERT INTO user(username, password, email, status, registration_start, code ) VALUES( ?, ?, ?, 'R', ?, ? )" + << user << password << email << now << code; + stmt.exec( ); + + return code; +} + +bool user::verify_registration_code( std::string code ) +{ + cppdb::session sql( cms.conn ); + cppdb::statement stmt; + stmt = sql << "UPDATE user set status='A' WHERE code=?" << code; + stmt.exec( ); + if( stmt.affected( ) == 1 ) { + return true; + } + + return false; +} + +void user::delete_user( std::string user ) +{ + cppdb::session sql( cms.conn ); + cppdb::statement stmt; + stmt = sql << "DELETE FROM user WHERE username=?" << user; + stmt.exec( ); +} + void user::ini( content::user &c ) { master::ini( c ); @@ -247,6 +347,7 @@ bool register_user_form::validate( ) if( captcha.value( ).compare( cms.user.last_captcha ) != 0 ) { captcha.valid( false ); captcha.clear( ); + booster::ptime::sleep( booster::ptime( 5, 0 ) ); return false; } @@ -273,15 +374,6 @@ 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; } |