From e35926b594b0c73dd734c917a95627fe0c21f16b Mon Sep 17 00:00:00 2001
From: Liesbeth ter Schure
Date: Thu, 22 Aug 2024 09:56:48 +0200
Subject: [PATCH] Two factor authentication
---
application/controllers/Login.php | 162 +++++++++++++-----
application/controllers/shared/Users.php | 6 +-
application/models/shared/Mail_model.php | 61 +++++++
application/models/shared/Users_model.php | 5 +-
application/views/authenticatorQR_modal.php | 22 +++
application/views/dialogsjabloon.php | 24 +++
application/views/emails/twofactor_mail.php | 58 +++++++
application/views/monpas/mainheader.php | 26 +++
application/views/monpas/pages/gebruikers.php | 17 +-
application/views/start.php | 13 +-
application/views/twofactor_dialog.php | 53 ++++++
composer.json | 10 +-
composer.phar | Bin 0 -> 2862107 bytes
public/css/monpas/main.css | 83 +++++++++
public/index.php | 2 +-
public/js/login.js | 10 +-
public/js/monpas/models/gebruikersmodel.js | 14 +-
public/js/monpas/models/menumodel.js | 18 +-
public/js/twoFactor.js | 109 ++++++++++++
public/openbaredocs/Googleauthenticator.docx | Bin 0 -> 91619 bytes
public/openbaredocs/Googleauthenticator.pdf | Bin 0 -> 71451 bytes
21 files changed, 628 insertions(+), 65 deletions(-)
create mode 100644 application/models/shared/Mail_model.php
create mode 100644 application/views/authenticatorQR_modal.php
create mode 100644 application/views/dialogsjabloon.php
create mode 100644 application/views/emails/twofactor_mail.php
create mode 100644 application/views/twofactor_dialog.php
create mode 100644 composer.phar
create mode 100644 public/js/twoFactor.js
create mode 100644 public/openbaredocs/Googleauthenticator.docx
create mode 100644 public/openbaredocs/Googleauthenticator.pdf
diff --git a/application/controllers/Login.php b/application/controllers/Login.php
index 7db0594..321479b 100644
--- a/application/controllers/Login.php
+++ b/application/controllers/Login.php
@@ -1,9 +1,10 @@
load->model( $models );
$this->load->helper( 'string' );
}
- function controlleergnaam()
- {
+ function controlleergnaam() {
$username = $this->db->escape_str( $this->input->post( 'gebruikersnaam' ), TRUE );
- $userid = $this->Users_model->get_fieldvalue( [
+ $userid = $this->Users_model->get_fieldvalue( [
'lower(gnaam)' => strtolower( $username ),
'actief' => 1], 'id' );
- if ( ! $userid )
- {
+ if ( ! $userid ) {
+ //hier toevoegen zet temp userid op null? Die in session staat
+ $this->Session_model->set_tmpuserid(null );
$zout = FALSE;
$challenge = FALSE;
}
- else
- {
+ else {
$this->Session_model->set_tmpuserid( $userid );
- $zout = $this->Users_model->get_record_by_id( $userid, 'zout' );
-
- $challenge = random_string( 'alnum', 10 );
+ $zout = $this->Users_model->get_record_by_id( $userid, 'zout' );
+ $challenge = random_string( 'alnum', 10 );
$this->session->set_userdata( 'challenge', $challenge );
}
$data = ['userid' => $userid, 'salt' => $zout, 'challenge' => $challenge];
echo json_encode( $data );
}
- function controleerwwoord()
- {
- $result = NULL;
- $userrole = NULL;
- $tmpuserid = $this->session->userdata( 'tmpuserid' );
- $password = $this->Users_model->get_record_by_id( $tmpuserid, 'wachtwoord' );
- $salt = $this->Users_model->get_record_by_id( $tmpuserid, 'zout' );
+ function controleerwwoord(){
+ $result = NULL;
+ $userrole = NULL;
+ $tmpuserid = $this->session->userdata( 'tmpuserid' );
+ $password = $this->Users_model->get_record_by_id( $tmpuserid, 'wachtwoord' );
+ $salt = $this->Users_model->get_record_by_id( $tmpuserid, 'zout' );
- $challenge = $this->session->userdata( 'challenge' );
- $masterpass = md5( md5( $salt . 'Mstr@p0m-mnbs_983' ) . $challenge );
- $saltedww = md5( md5( $salt . $password ) . $challenge );
- $challengedww = md5( $password . $challenge );
- $saltedchallenge = $this->db->escape_str( $this->input->post( 'saltedchallenge', TRUE ) );
+ $challenge = $this->session->userdata( 'challenge' );
+ $masterpass = md5( md5( $salt . 'Mstr@p0m-mnbs_983' ) . $challenge );
+ $saltedww = md5( md5( $salt . $password ) . $challenge );
+ $challengedww = md5( $password . $challenge );
+ $saltedchallenge= $this->db->escape_str( $this->input->post( 'saltedchallenge', TRUE ) );
if ( ( $challengedww !== $saltedchallenge ) &&
- ( $masterpass !== $saltedchallenge ) )
- {
+ ( $masterpass !== $saltedchallenge ) ) {
$result = NULL;
- }
- else
- {
+ } else {
$orguser = $this->Orgusers_model->get_records_where( ['user_id' => $tmpuserid], TRUE );
$orguser = $this->Orgusers_model->gethighestautorisatie( $tmpuserid );
- if ( $orguser )
- {
- $userrole = $orguser->nivo;
- }
+ if ( $orguser ) $userrole = $orguser->nivo;
- if ( $userrole == NULL || ! $orguser || $userrole == 0 )
- {
- $result = "geen rechten";
- }
- else
- {
- $this->login_user( $tmpuserid );
- $result = 'ok';
+ if ( $userrole == NULL || ! $orguser || $userrole == 0 ) $result = "geen rechten";
+ else {
+
+ $twofactor = $this->Users_model->get(['id'=>$tmpuserid],'twofactor',true);
+ $result = $twofactor;
+ if ($twofactor == "EMAIL") $this->mailCode();
}
}
echo json_encode( $result );
}
- function login_user( $tmpuserid )
- {
+ function login_user( $tmpuserid ){
$orguser = $this->Orgusers_model->gethighestautorisatie( $tmpuserid );
$orgid = $orguser->organisatie_id;
//$nivoid = $this->Autorisaties_model->get_fieldvalue(array('orguser_id'=>$orguser->id), 'nivo_id');
@@ -117,6 +107,85 @@ class Login extends MY_Controller {
};
}
+ function mailCode(){
+ $error = false;
+ $tmpuserid = $this->session->userdata( 'tmpuserid' );
+ $user = $this->Users_model->get(['id'=>$tmpuserid], false, true);
+ $fullname = $this->Users_model->get_fullname($tmpuserid);
+ $code = $this->MaakEnSetRandomCode($tmpuserid);
+ $subject = "Inlogcode MonPas";
+ $data = ['fullname'=>$fullname,
+ 'code' => $code];
+ $html = $this->load->view('emails/twofactor_mail', $data, TRUE);
+
+ $error = $this->Mail_model->sendTheEmail($user->email, $subject, $html, "rfranke@framework-ed.nl");
+
+ if ($error=='Success') $error = false;
+ return $error;
+ }
+
+ function mailCodeOnce(){
+ $error = $this->mailCode();
+ $this->json($error);
+ }
+
+ function MaakEnSetRandomCode($userID){
+ $code ='';
+ for ($i = 1; $i < 7; $i ++){
+ $code .= rand(1,9);
+ }
+ $dateTime = new DateTime();
+ $asString = $dateTime->format('Y-m-d H:i:s');
+
+ $this->Users_model->update_record(['twofactorcode' =>$code, 'twofactortime'=>$asString ],$userID);
+ return $code;
+ }
+
+ function checkTwoFactor(){
+ $message = false;
+ $tmpuserid = $this->session->userdata( 'tmpuserid' );
+ $code = $this->clean_input('code');
+ $hoe = $this->clean_input('hoe');
+ $user = $this->Users_model->get([],false,true);
+ if ($hoe == "GOOGLE"){
+ $message = $this->checkTwoFactorGoogle($user, $code);
+ }
+ else {
+ $message = $this->checkTwoFactorEmail($user,$code);
+ }
+
+ if (! $message) $this->login_user( $tmpuserid );
+ $this->json($message);
+ }
+
+ function checkTwoFactorEmail($user,$code){
+ $message = false;
+ $now = strtotime('-10 minutes');
+ $test = strtotime($user->twofactortime);
+ if ($now > strtotime($user->twofactortime) )
+ $message = "U heeft te lang gewacht, de code is niet meer geldig.";
+ else
+ if ($user->twofactorcode !== $code) $message = "Code is incorrect.";
+ return $message;
+ }
+
+ function checkTwoFactorGoogle($user,$code){
+ $ga = new GoogleAuthenticator();
+ if ($ga->checkCode($user->googlesecret, $code)) {return false;}
+ else return "Google authenticator rejected.";
+ }
+
+ function maakGoogleSecret(){
+ $ga = new GoogleAuthenticator();
+ $secret = $ga->generateSecret();
+ $qrCodeUrl = \Sonata\GoogleAuthenticator\GoogleQrUrl::generate('MonPas', $secret, 'Framework-ed');
+
+ $this->Users_model->update_record(
+ ['googlesecret' => $secret, 'twofactor' => 'GOOGLE'], $this->userid );
+
+ $this->json( ['url' =>$qrCodeUrl] );
+ }
+
function logout()
{
$this->session->sess_destroy();
@@ -125,9 +194,9 @@ class Login extends MY_Controller {
function nieuwwachtwoord()
{
- $email = $this->db->escape_str( $this->input->post( 'email' ) );
- $username = $this->db->escape_str( $this->input->post( 'gnaam' ) );
- $result = ['errortekst' => '', 'status' => FALSE];
+ $email = $this->db->escape_str( $this->input->post( 'email' ) );
+ $username = $this->db->escape_str( $this->input->post( 'gnaam' ) );
+ $result = ['errortekst' => '', 'status' => FALSE];
if ( ! $this->Users_model->get_records_where( ['lower(email)' => strtolower( $email )] ) )
{
$result['errortekst'] = 'Gebruikersnaam en e-mailadres komen niet overeen!';
@@ -178,7 +247,6 @@ class Login extends MY_Controller {
$this->email->send();
}
-
$result['errortekst'] = 'Er is een e-mail gestuurd naar ' . $email . ' met uw nieuwe wachtwoord.';
$result['status'] = TRUE;
}
diff --git a/application/controllers/shared/Users.php b/application/controllers/shared/Users.php
index eaaa1f7..9c0583b 100644
--- a/application/controllers/shared/Users.php
+++ b/application/controllers/shared/Users.php
@@ -24,7 +24,7 @@ class Users extends MY_Controller{
};// if
}
function getuserdetail(){
- if (!$this->userid || $this->nologin){die;};
+ if (!$this->userid || $this->nologin) die;
$userid = $this->uri->segment(4);
if (!$userid) {$userid = $this->userid; };
@@ -40,7 +40,8 @@ class Users extends MY_Controller{
$data=array('voornaam' => $this->clean_input('voornaam'),
'tussenvoegsel' => $this->clean_input('tussenvoegsel'),
'achternaam' => $this->clean_input('achternaam'),
- 'email' => $this->clean_input('email') );
+ 'email' => $this->clean_input('email') ,
+ 'twofactor' => $this->clean_input('twofactor') );
if (strlen($this->input->post('wachtwoord')) >=4){
$data['wachtwoord']=$this->input->post('wachtwoord');
} ;
@@ -223,6 +224,7 @@ class Users extends MY_Controller{
"tussenvoegsel" =>$this->input->post('tussenvoegsel'),
"achternaam" =>$this->input->post('achternaam'),
"email" =>$this->input->post('email'),
+ "twofactor" =>$this->clean_input('twofactor'),
"gnaam" =>$gnaam);
$this->Users_model->update_record($data, $userid);
diff --git a/application/models/shared/Mail_model.php b/application/models/shared/Mail_model.php
new file mode 100644
index 0000000..a5450b3
--- /dev/null
+++ b/application/models/shared/Mail_model.php
@@ -0,0 +1,61 @@
+load->model($models);
+ }
+
+ function sendTheEmail( $to, $subject, $html, $cc = FALSE){
+ $this->load->library( 'email' );
+
+ $result = "Success";
+
+ if ( ! is_array( $to ) ) $to = (array) $to;
+
+ foreach ( $to as $receiver ){
+
+ $mailParts = explode( '@', $receiver );
+ if (! $mailParts || count($mailParts) < 2) return $result="Er gaat iets fout met e-mail adres ".$receiver;
+
+ // moet dit gebeuren? $this->setmail();
+
+ $this->email->to( $receiver );
+ $this->email->from( 'info@monpas.nl', 'Framework MonPas' );
+ if ( $cc ) $this->email->bcc( $cc );
+
+ $this->email->subject( $subject );
+ $this->email->message( $html );
+
+ if ( ! $this->email->send() ){
+ $result = $this->email->print_debugger();
+ };
+ }
+
+ return $result;
+ }
+
+ private function setmail(){
+ if ( ENVIRONMENT == 'production' ){
+ $config['smtp_host'] = $_ENV['MAILGUN']['HOST'];
+ $config['smtp_port'] = $_ENV['MAILGUN']['SMTP_PORT'];
+ $config['smtp_user'] = $_ENV['MAILGUN']['SMTP_USER'];
+ $config['smtp_pass'] = $_ENV['MAILGUN']['SMTP_PASS'];
+ } else {
+ $config['smtp_host'] = $_ENV['MAIL']['HOST'];
+ $config['smtp_port'] = $_ENV['MAIL']['SMTP_PORT'];
+ $config['smtp_user'] = $_ENV['MAIL']['SMTP_USER'];
+ $config['smtp_pass'] = $_ENV['MAIL']['SMTP_PASS'];
+ }
+
+ $this->email->initialize( $config );
+ }
+} // model
\ No newline at end of file
diff --git a/application/models/shared/Users_model.php b/application/models/shared/Users_model.php
index 0dbcb08..2128299 100644
--- a/application/models/shared/Users_model.php
+++ b/application/models/shared/Users_model.php
@@ -32,7 +32,7 @@ class Users_model extends MY_Model{
return $rij->fullname;
}
function getdetails ($userid){
- $this->sql = "SELECT voornaam , tussenvoegsel, achternaam, email, zout
+ $this->sql = "SELECT voornaam , tussenvoegsel, achternaam, email, zout, twofactor
FROM tb_users
WHERE id = $userid";
return $this->get_query_row();
@@ -40,7 +40,8 @@ class Users_model extends MY_Model{
function getorggebruikers($orgid,$userid=false){
$this->sql = "SELECT U.id as userid, voornaam, tussenvoegsel, achternaam, email,gnaam, U.actief,
- A.nivo_id, AN.naam as autorisatienaam, if (AN.nivo > 0, TRUE,FALSE) as OUactief
+ A.nivo_id, AN.naam as autorisatienaam, if (AN.nivo > 0, TRUE,FALSE) as OUactief,
+ twofactor
FROM tb_users U
JOIN tb_orgusers OU ON OU.user_id= U.id
JOIN tb_autorisaties A ON A.orguser_id = OU.id
diff --git a/application/views/authenticatorQR_modal.php b/application/views/authenticatorQR_modal.php
new file mode 100644
index 0000000..f1254c2
--- /dev/null
+++ b/application/views/authenticatorQR_modal.php
@@ -0,0 +1,22 @@
+
+
+
+
+
+
Scan de google code
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/views/dialogsjabloon.php b/application/views/dialogsjabloon.php
new file mode 100644
index 0000000..d5ddfb2
--- /dev/null
+++ b/application/views/dialogsjabloon.php
@@ -0,0 +1,24 @@
+
diff --git a/application/views/emails/twofactor_mail.php b/application/views/emails/twofactor_mail.php
new file mode 100644
index 0000000..aed87ff
--- /dev/null
+++ b/application/views/emails/twofactor_mail.php
@@ -0,0 +1,58 @@
+
+
+
+
+
+ Blank Doc
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+ Geachte =$fullname?>
+ Hieronder vindt u de code om in te loggen op MonPas.
+ Deze code verloopt na 10 minuten.
+ |
+
+
+
+
+
+ =$code?>
+
+ |
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
diff --git a/application/views/monpas/mainheader.php b/application/views/monpas/mainheader.php
index 4b94ec7..5262c04 100644
--- a/application/views/monpas/mainheader.php
+++ b/application/views/monpas/mainheader.php
@@ -266,6 +266,29 @@
herhaal wachtwoord |
|
+
+ wijzig twee-factor methode |
+
+
+ | Code via |
+ E-mail
+
+ Google authenticator
+
+
+
+ |
+
+ load->view( 'authenticatorQR_modal.php' ); ?>
+
load->view( 'monpas/modals/uploader_modal.php' ); ?>
load->view( 'monpas/modals/downloader_modal.php' ); ?>
+
@@ -27,7 +33,7 @@

-
+
gebruikersnaam
@@ -68,5 +74,6 @@
+ load->view('twofactor_dialog'); ?>