summaryrefslogtreecommitdiff
path: root/src/user.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/user.cpp')
-rw-r--r--src/user.cpp118
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;
}