2016-09-11 01:58:06 +02:00
< ? php
2023-06-24 23:18:39 +02:00
/*
FusionPBX
Version : MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 ( the " License " ); you may not use this file except in compliance with
the License . You may obtain a copy of the License at
http :// www . mozilla . org / MPL /
Software distributed under the License is distributed on an " AS IS " basis ,
WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
for the specific language governing rights and limitations under the
License .
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Mark J Crane < markjcrane @ fusionpbx . com >
2024-09-29 00:37:36 +02:00
Portions created by the Initial Developer are Copyright ( C ) 2008 - 2024
2023-06-24 23:18:39 +02:00
the Initial Developer . All Rights Reserved .
Contributor ( s ) :
Mark J Crane < markjcrane @ fusionpbx . com >
*/
2016-09-11 01:58:06 +02:00
/**
2023-04-16 09:10:39 +02:00
* plugin_database
2016-09-11 01:58:06 +02:00
*
2023-05-12 02:58:22 +02:00
* @ method plugin_database validates the authentication using information from the database
2016-09-11 01:58:06 +02:00
*/
class plugin_database {
/**
* Define variables and their scope
*/
public $domain_name ;
public $domain_uuid ;
public $user_uuid ;
2016-09-11 06:22:37 +02:00
public $contact_uuid ;
2024-09-29 00:37:36 +02:00
public $contact_organization ;
public $contact_name_given ;
public $contact_name_family ;
public $contact_image ;
2016-09-11 01:58:06 +02:00
public $username ;
public $password ;
public $key ;
2023-05-05 18:46:37 +02:00
public $debug ;
2024-03-29 05:10:36 +01:00
public $user_email ;
2016-09-11 01:58:06 +02:00
/**
* database checks the local database to authenticate the user or key
* @ return array [ authorized ] => true or false
*/
2024-09-07 02:20:26 +02:00
function database ( authentication $auth , settings $settings ) {
2016-09-11 01:58:06 +02:00
2023-05-07 02:31:48 +02:00
//pre-process some settings
2024-09-07 02:20:26 +02:00
$theme_favicon = $settings -> get ( 'theme' , 'favicon' , PROJECT_PATH . '/themes/default/favicon.ico' );
$theme_logo = $settings -> get ( 'theme' , 'logo' , PROJECT_PATH . '/themes/default/images/logo_login.png' );
$theme_login_logo_width = $settings -> get ( 'theme' , 'login_logo_width' , 'auto; max-width: 300px' );
$theme_login_logo_height = $settings -> get ( 'theme' , 'login_logo_height' , 'auto; max-height: 300px' );
$theme_message_delay = 1000 * ( float ) $settings -> get ( 'theme' , 'message_delay' , 3000 );
2024-09-10 12:03:44 +02:00
$background_videos = $settings -> get ( 'theme' , 'background_video' , null );
$theme_background_video = ( isset ( $background_videos ) && is_array ( $background_videos )) ? $background_videos [ 0 ] : null ;
2024-09-07 02:20:26 +02:00
$login_domain_name_visible = $settings -> get ( 'login' , 'domain_name_visible' );
$login_domain_name = $settings -> get ( 'login' , 'domain_name' );
$login_destination = $settings -> get ( 'login' , 'destination' );
$users_unique = $settings -> get ( 'users' , 'unique' , '' );
//check if already authorized
2023-04-16 09:10:39 +02:00
if ( isset ( $_SESSION [ 'authentication' ][ 'plugin' ][ 'database' ]) && $_SESSION [ 'authentication' ][ 'plugin' ][ 'database' ][ " authorized " ]) {
2024-10-11 00:21:03 +02:00
return ;
2023-04-16 09:10:39 +02:00
}
//show the authentication code view
2023-05-11 05:53:39 +02:00
if ( empty ( $_REQUEST [ " username " ]) && empty ( $_REQUEST [ " key " ])) {
2023-04-16 09:10:39 +02:00
//get the domain
$domain_array = explode ( " : " , $_SERVER [ " HTTP_HOST " ]);
$domain_name = $domain_array [ 0 ];
//create token
//$object = new token;
//$token = $object->create('login');
//add multi-lingual support
$language = new text ;
$text = $language -> get ( null , '/core/authentication' );
//initialize a template object
$view = new template ();
$view -> engine = 'smarty' ;
$view -> template_dir = $_SERVER [ " DOCUMENT_ROOT " ] . PROJECT_PATH . '/core/authentication/resources/views/' ;
2024-06-26 15:28:37 +02:00
$view -> cache_dir = sys_get_temp_dir ();
2023-04-16 09:10:39 +02:00
$view -> init ();
//add translations
$view -> assign ( " login_title " , $text [ 'button-login' ]);
$view -> assign ( " label_username " , $text [ 'label-username' ]);
$view -> assign ( " label_password " , $text [ 'label-password' ]);
2024-08-20 02:57:05 +02:00
$view -> assign ( " label_domain " , $text [ 'label-domain' ]);
2023-04-16 09:10:39 +02:00
$view -> assign ( " button_login " , $text [ 'button-login' ]);
//assign default values to the template
2023-05-11 07:08:57 +02:00
$view -> assign ( " project_path " , PROJECT_PATH );
2024-09-07 02:20:26 +02:00
$view -> assign ( " login_destination_url " , $login_destination );
$view -> assign ( " login_domain_name_visible " , $login_domain_name_visible );
2024-09-29 00:37:36 +02:00
$view -> assign ( " login_domain_names " , $login_domain_name );
2024-09-07 02:20:26 +02:00
$view -> assign ( " favicon " , $theme_favicon );
$view -> assign ( " login_logo_width " , $theme_login_logo_width );
$view -> assign ( " login_logo_height " , $theme_login_logo_height );
$view -> assign ( " login_logo_source " , $theme_logo );
$view -> assign ( " message_delay " , $theme_message_delay );
$view -> assign ( " background_video " , $theme_background_video );
2023-06-25 03:11:49 +02:00
if ( ! empty ( $_SESSION [ 'username' ])) {
2023-06-24 23:18:39 +02:00
$view -> assign ( " login_password_description " , $text [ 'label-password_description' ]);
$view -> assign ( " username " , $_SESSION [ 'username' ]);
$view -> assign ( " button_cancel " , $text [ 'button-cancel' ]);
}
2023-06-18 01:16:39 +02:00
//messages
$view -> assign ( 'messages' , message :: html ( true , ' ' ));
2023-04-16 09:10:39 +02:00
//add the token name and hash to the view
//$view->assign("token_name", $token['name']);
//$view->assign("token_hash", $token['hash']);
//show the views
$content = $view -> render ( 'login.htm' );
echo $content ;
exit ;
}
//validate the token
//$token = new token;
//if (!$token->validate($_SERVER['PHP_SELF'])) {
// message::add($text['message-invalid_token'],'negative');
// header('Location: domains.php');
// exit;
//}
//add the authentication details
2023-04-18 06:15:02 +02:00
if ( isset ( $_REQUEST [ " username " ])) {
2023-04-16 09:10:39 +02:00
$this -> username = $_REQUEST [ " username " ];
2023-05-06 22:43:20 +02:00
$_SESSION [ 'username' ] = $this -> username ;
2023-04-18 06:15:02 +02:00
}
if ( isset ( $_REQUEST [ " password " ])) {
2023-04-16 09:10:39 +02:00
$this -> password = $_REQUEST [ " password " ];
}
if ( isset ( $_REQUEST [ " key " ])) {
$this -> key = $_REQUEST [ " key " ];
}
2024-08-20 02:57:05 +02:00
if ( isset ( $_REQUEST [ " domain_name " ])) {
$domain_name = $_REQUEST [ " domain_name " ];
$this -> domain_name = $_REQUEST [ " domain_name " ];
}
2023-04-16 09:10:39 +02:00
2023-05-12 02:58:22 +02:00
//get the domain name
$auth -> get_domain ();
2023-06-28 22:54:34 +02:00
$this -> username = $_SESSION [ 'username' ] ? ? null ;
2024-08-20 02:57:05 +02:00
//$this->domain_uuid = $_SESSION['domain_uuid'] ?? null;
//$this->domain_name = $_SESSION['domain_name'] ?? null;
2023-05-12 02:58:22 +02:00
2023-05-12 03:55:37 +02:00
//debug information
//echo "domain_uuid: ".$this->domain_uuid."<br />\n";
2024-08-20 02:57:05 +02:00
//view_array($this->domain_uuid, false);
2023-05-12 03:55:37 +02:00
//echo "domain_name: ".$this->domain_name."<br />\n";
//echo "username: ".$this->username."<br />\n";
2019-09-02 23:57:18 +02:00
//set the default status
$user_authorized = false ;
2016-09-11 01:58:06 +02:00
2024-09-29 00:37:36 +02:00
//check if contacts app exists
$contacts_exists = file_exists ( $_SERVER [ " DOCUMENT_ROOT " ] . PROJECT_PATH . '/app/contacts/' ) ? true : false ;
2016-09-11 01:58:06 +02:00
//check the username and password if they don't match then redirect to the login
2024-09-29 00:37:36 +02:00
$sql = " select " ;
$sql .= " d.domain_name, " ;
$sql .= " u.user_uuid, " ;
$sql .= " u.contact_uuid, " ;
$sql .= " u.username, " ;
$sql .= " u.password, " ;
$sql .= " u.user_email, " ;
$sql .= " u.salt, " ;
$sql .= " u.api_key, " ;
$sql .= " u.domain_uuid " ;
if ( $contacts_exists ) {
$sql .= " , " ;
$sql .= " c.contact_organization, " ;
$sql .= " c.contact_name_given, " ;
$sql .= " c.contact_name_family, " ;
$sql .= " a.contact_attachment_uuid " ;
}
$sql .= " from " ;
$sql .= " v_domains as d, " ;
$sql .= " v_users as u " ;
if ( $contacts_exists ) {
$sql .= " left join v_contacts as c on u.contact_uuid = c.contact_uuid and u.contact_uuid is not null " ;
$sql .= " left join v_contact_attachments as a on u.contact_uuid = a.contact_uuid and u.contact_uuid is not null and a.attachment_primary = 1 and a.attachment_filename is not null and a.attachment_content is not null " ;
}
$sql .= " where " ;
$sql .= " u.domain_uuid = d.domain_uuid " ;
$sql .= " and ( " ;
$sql .= " user_type = 'default' " ;
$sql .= " or user_type is null " ;
$sql .= " ) " ;
2023-05-06 22:43:20 +02:00
if ( isset ( $this -> key ) && strlen ( $this -> key ) > 30 ) {
2020-10-27 02:22:46 +01:00
$sql .= " and u.api_key = :api_key " ;
2019-09-02 23:57:18 +02:00
$parameters [ 'api_key' ] = $this -> key ;
2016-09-11 01:58:06 +02:00
}
else {
2023-05-06 22:43:20 +02:00
$sql .= " and ( \n " ;
$sql .= " lower(u.username) = lower(:username) \n " ;
$sql .= " or lower(u.user_email) = lower(:username) \n " ;
$sql .= " ) \n " ;
2019-09-02 23:57:18 +02:00
$parameters [ 'username' ] = $this -> username ;
2016-09-11 01:58:06 +02:00
}
2024-09-07 02:20:26 +02:00
if ( $users_unique === " global " ) {
2019-09-19 04:09:11 +02:00
//unique username - global (example: email address)
}
else {
//unique username - per domain
2020-10-27 02:22:46 +01:00
$sql .= " and u.domain_uuid = :domain_uuid " ;
2019-09-02 23:57:18 +02:00
$parameters [ 'domain_uuid' ] = $this -> domain_uuid ;
2016-09-11 01:58:06 +02:00
}
$sql .= " and (user_enabled = 'true' or user_enabled is null) " ;
2024-09-07 02:20:26 +02:00
$row = $settings -> database () -> select ( $sql , $parameters , 'row' );
2023-06-25 03:11:49 +02:00
if ( ! empty ( $row ) && is_array ( $row ) && @ sizeof ( $row ) != 0 ) {
2023-04-16 09:10:39 +02:00
2020-03-06 09:09:12 +01:00
//validate the password
$valid_password = false ;
if ( isset ( $this -> key ) && strlen ( $this -> key ) > 30 && $this -> key === $row [ " api_key " ]) {
$valid_password = true ;
2019-09-02 23:57:18 +02:00
}
2020-03-06 09:09:12 +01:00
else if ( substr ( $row [ " password " ], 0 , 1 ) === '$' ) {
2023-05-05 18:46:37 +02:00
if ( isset ( $this -> password ) && ! empty ( $this -> password )) {
2020-03-06 09:09:12 +01:00
if ( password_verify ( $this -> password , $row [ " password " ])) {
2023-04-16 09:10:39 +02:00
$valid_password = true ;
2020-03-06 09:09:12 +01:00
}
}
2019-09-02 23:57:18 +02:00
}
2019-09-19 04:09:11 +02:00
else {
2020-03-06 09:09:12 +01:00
//deprecated - compare the password provided by the user with the one in the database
if ( md5 ( $row [ " salt " ] . $this -> password ) === $row [ " password " ]) {
$row [ " password " ] = crypt ( $this -> password , '$1$' . $password_salt . '$' );
$valid_password = true ;
}
}
2023-07-22 22:21:11 +02:00
//set the domain and user settings
if ( $valid_password ) {
//set the domain_uuid
$this -> domain_uuid = $row [ " domain_uuid " ];
$this -> domain_name = $row [ " domain_name " ];
//set the domain session variables
$_SESSION [ " domain_uuid " ] = $this -> domain_uuid ;
$_SESSION [ " domain_name " ] = $this -> domain_name ;
//set the domain setting
2024-09-07 02:20:26 +02:00
if ( $users_unique === " global " && $row [ " domain_uuid " ] !== $this -> domain_uuid ) {
2023-07-22 22:21:11 +02:00
$domain = new domains ();
$domain -> set ();
}
//set the variables
$this -> user_uuid = $row [ 'user_uuid' ];
$this -> username = $row [ 'username' ];
$this -> user_email = $row [ 'user_email' ];
$this -> contact_uuid = $row [ 'contact_uuid' ];
2024-09-29 00:37:36 +02:00
if ( $contacts_exists ) {
$this -> contact_organization = $row [ 'contact_organization' ];
$this -> contact_name_given = $row [ 'contact_name_given' ];
$this -> contact_name_family = $row [ 'contact_name_family' ];
$this -> contact_image = $row [ 'contact_attachment_uuid' ];
}
2023-07-22 22:21:11 +02:00
//debug info
//echo "user_uuid ".$this->user_uuid."<br />\n";
//echo "username ".$this->username."<br />\n";
//echo "contact_uuid ".$this->contact_uuid."<br />\n";
//set a few session variables
$_SESSION [ " user_uuid " ] = $row [ 'user_uuid' ];
$_SESSION [ " username " ] = $row [ 'username' ];
$_SESSION [ " user_email " ] = $row [ 'user_email' ];
$_SESSION [ " contact_uuid " ] = $row [ " contact_uuid " ];
}
2020-03-06 09:09:12 +01:00
//check to to see if the the password hash needs to be updated
if ( $valid_password ) {
//set the password hash cost
$options = array ( 'cost' => 10 );
//check if a newer hashing algorithm is available or the cost has changed
if ( password_needs_rehash ( $row [ " password " ], PASSWORD_DEFAULT , $options )) {
//build user insert array
2024-09-07 02:20:26 +02:00
$array = [];
2020-03-06 09:09:12 +01:00
$array [ 'users' ][ 0 ][ 'user_uuid' ] = $this -> user_uuid ;
$array [ 'users' ][ 0 ][ 'domain_uuid' ] = $this -> domain_uuid ;
2023-05-06 22:43:20 +02:00
$array [ 'users' ][ 0 ][ 'user_email' ] = $this -> user_email ;
2020-03-06 09:09:12 +01:00
$array [ 'users' ][ 0 ][ 'password' ] = password_hash ( $this -> password , PASSWORD_DEFAULT , $options );
$array [ 'users' ][ 0 ][ 'salt' ] = null ;
//build user group insert array
$array [ 'user_groups' ][ 0 ][ 'user_group_uuid' ] = uuid ();
$array [ 'user_groups' ][ 0 ][ 'domain_uuid' ] = $this -> domain_uuid ;
$array [ 'user_groups' ][ 0 ][ 'group_name' ] = 'user' ;
$array [ 'user_groups' ][ 0 ][ 'user_uuid' ] = $this -> user_uuid ;
//grant temporary permissions
$p = new permissions ;
$p -> add ( 'user_edit' , 'temp' );
//execute insert
2024-09-07 02:20:26 +02:00
$settings -> database () -> app_name = 'authentication' ;
$settings -> database () -> app_uuid = 'a8a12918-69a4-4ece-a1ae-3932be0e41f1' ;
$settings -> database () -> save ( $array );
2020-03-06 09:09:12 +01:00
unset ( $array );
//revoke temporary permissions
$p -> delete ( 'user_edit' , 'temp' );
}
2023-06-27 04:32:11 +02:00
2019-09-19 04:09:11 +02:00
}
2016-09-11 01:58:06 +02:00
2023-06-27 04:32:11 +02:00
//result array
if ( $valid_password ) {
$result [ " plugin " ] = " database " ;
$result [ " domain_name " ] = $this -> domain_name ;
$result [ " username " ] = $this -> username ;
$result [ " user_uuid " ] = $this -> user_uuid ;
$result [ " domain_uuid " ] = $_SESSION [ 'domain_uuid' ];
$result [ " contact_uuid " ] = $this -> contact_uuid ;
2024-09-29 00:37:36 +02:00
if ( $contacts_exists ) {
$result [ " contact_organization " ] = $this -> contact_organization ;
$result [ " contact_name_given " ] = $this -> contact_name_given ;
$result [ " contact_name_family " ] = $this -> contact_name_family ;
$result [ " contact_image " ] = $this -> contact_image ;
}
2023-06-27 04:32:11 +02:00
$result [ " user_email " ] = $this -> user_email ;
$result [ " sql " ] = $sql ;
$result [ " authorized " ] = $valid_password ;
}
//return the results
return $result ? ? false ;
}
2016-09-11 01:58:06 +02:00
2023-06-27 04:32:11 +02:00
return ;
2023-04-16 09:10:39 +02:00
2016-09-11 01:58:06 +02:00
}
}
2024-08-20 02:57:05 +02:00
?>