From e405e375f66d822e58e7a2fdf9989897c3657d86 Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Sun, 23 Apr 2023 01:26:51 -0600 Subject: [PATCH] Add totp and enhance api key --- core/users/user_edit.php | 130 ++++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 14 deletions(-) diff --git a/core/users/user_edit.php b/core/users/user_edit.php index a3b35728db..1f0f8acef3 100644 --- a/core/users/user_edit.php +++ b/core/users/user_edit.php @@ -17,7 +17,7 @@ The Initial Developer of the Original Code is Mark J Crane - Portions created by the Initial Developer are Copyright (C) 2008-2020 + Portions created by the Initial Developer are Copyright (C) 2008-2023 the Initial Developer. All Rights Reserved. Contributor(s): @@ -128,6 +128,7 @@ $user_status = $_POST["user_status"]; $user_language = $_POST["user_language"]; $user_time_zone = $_POST["user_time_zone"]; + if (permission_exists('contact_edit') && $action == 'edit') { $contact_uuid = $_POST["contact_uuid"]; } @@ -144,6 +145,9 @@ if (permission_exists('message_key')) { $message_key = $_POST["message_key"]; } + if (in_array('totp', $_SESSION['authentication']['methods'])) { + $user_totp_secret = strtoupper($_POST["user_totp_secret"]); + } //validate the token $token = new token; @@ -506,6 +510,9 @@ if (permission_exists('api_key')) { $array['users'][$x]['api_key'] = ($api_key != '') ? $api_key : null; } + if (in_array('totp', $_SESSION['authentication']['methods'])) { + $array['users'][$x]['user_totp_secret'] = $user_totp_secret; + } $array['users'][$x]['user_enabled'] = $user_enabled; if (permission_exists('contact_add')) { $array['users'][$x]['contact_uuid'] = ($contact_uuid != '') ? $contact_uuid : null; @@ -584,7 +591,8 @@ else { //populate the form with values from db if ($action == 'edit') { - $sql = "select domain_uuid, user_uuid, username, user_email, api_key, user_enabled, contact_uuid, cast(user_enabled as text), user_status "; + $sql = "select domain_uuid, user_uuid, username, user_email, api_key, user_totp_secret, "; + $sql .= "user_enabled, contact_uuid, cast(user_enabled as text), user_status "; $sql .= "from v_users "; $sql .= "where user_uuid = :user_uuid "; if (!permission_exists('user_all')) { @@ -600,6 +608,7 @@ $username = $row["username"]; $user_email = $row["user_email"]; $api_key = $row["api_key"]; + $user_totp_secret = $row["user_totp_secret"]; $user_enabled = $row["user_enabled"]; if (permission_exists('contact_view')) { $contact_uuid = $row["contact_uuid"]; @@ -1030,8 +1039,36 @@ echo " "; echo " ".$text['label-api_key'].""; echo " \n"; - echo " "; - echo button::create(['type'=>'button','label'=>$text['button-generate'],'icon'=>'key','onclick'=>"document.getElementById('api_key').value = '".generate_password(32,3)."';"]); + echo " "; + if (strlen($api_key) == 0) { + //generate api key + echo button::create(['type'=>'button', + 'label'=>$text['button-generate'], + 'icon'=>'key', + 'onclick'=>"document.getElementById('api_key').value = '".generate_password(32,3)."'; + document.getElementById('frm').submit();"]); + } + else { + //view the api key + echo button::create(['type'=>'button', + 'label'=>$text['button-view'], + 'id'=>'button-api_key_view', + 'icon'=>'key', + 'onclick'=>"document.getElementById ('button-api_key_view').style.display = 'none'; + document.getElementById('api_key').style.display = 'inline'; + document.getElementById('button-api_key_hide').style.display = 'inline'; + document.getElementById('button-api_key_view').style.display = 'none';"]); + + echo button::create(['type'=>'button', + 'label'=>$text['button-hide'], + 'id'=>'button-api_key_hide', + 'icon'=>'key', + 'style'=>'display: none;', + 'onclick'=>"document.getElementById('api_key').style.display = 'none'; + document.getElementById('button-api_key_hide').style.display = 'none'; + document.getElementById('button-api_key_view').style.display = 'inline';"]); + + } if (strlen($text['description-api_key']) > 0) { echo "
".$text['description-api_key']."
\n"; } @@ -1039,17 +1076,82 @@ echo " "; } - if (permission_exists('message_key')) { - echo " "; - echo " ".$text['label-message_key'].""; - echo " \n"; - echo " "; - echo button::create(['type'=>'button','label'=>$text['button-generate'],'icon'=>'key','onclick'=>"document.getElementById('message_key').value = '".generate_password(32,3)."';"]); - if (strlen($text['description-message_key']) > 0) { - echo "
".$text['description-message_key']."
\n"; + //user time based one time password secret + if (in_array('totp', $_SESSION['authentication']['methods'])) { + if ($user_totp_secret != '' && $username != '') { + $otpauth = "otpauth://totp/".$username."?secret=".$user_totp_secret."&issuer=".$_SESSION['domain_name']; + + require_once 'resources/qr_code/QRErrorCorrectLevel.php'; + require_once 'resources/qr_code/QRCode.php'; + require_once 'resources/qr_code/QRCodeImage.php'; + + try { + $code = new QRCode (- 1, QRErrorCorrectLevel::H); + $code->addData($otpauth); + $code->make(); + $img = new QRCodeImage ($code, $width=210, $height=210, $quality=50); + $img->draw(); + $image = $img->getImage(); + $img->finish(); + } + catch (Exception $error) { + echo $error; + } } - echo " "; - echo " "; + echo "\n"; + echo "\n"; + echo " ".$text['label-user_totp_secret']."\n"; + echo "\n"; + echo "\n"; + echo " "; + if (strlen($user_totp_secret) == 0) { + echo button::create(['type'=>'button', + 'label'=>$text['button-setup'], + 'icon'=>'key', + 'onclick'=>"document.getElementById('user_totp_secret').value = '".strtoupper(generate_password(32,3))."'; + document.getElementById('frm').submit();"]); + } + else { + echo " \n"; + echo button::create(['type'=>'button', + 'label'=>$text['button-view'], + 'id'=>'button-totp_view', + 'icon'=>'key', + 'onclick'=>"document.getElementById ('totp_qr').style.display = 'inline'; + document.getElementById ('button-totp_hide').style.display = 'inline'; + document.getElementById ('button-totp_disable').style.display = 'inline'; + document.getElementById ('button-totp_view').style.display = 'none';"]); + + echo button::create(['type'=>'button', + 'label'=>$text['button-hide'], + 'id'=>'button-totp_hide', + 'icon'=>'key', + 'style'=>'display: none;', + 'onclick'=>"document.getElementById ('totp_qr').style.display = 'none'; + document.getElementById ('button-totp_hide').style.display = 'none'; + document.getElementById ('button-totp_disable').style.display = 'none'; + document.getElementById ('button-totp_view').style.display = 'inline';"]); + + echo button::create(['type'=>'button', + 'label'=>$text['button-disable'], + 'id'=>'button-totp_disable', + 'icon'=>'trash', + 'style'=>'display: none;', + 'onclick'=>"document.getElementById('user_totp_secret').value = ''; + document.getElementById('frm').submit();"]); + } + if (strlen($user_totp_secret) == 0) { + echo "
".$text['description-user_totp_secret']."
\n"; + } + else { + echo "
".$text['description-user_totp_view']."
\n"; + } + echo "\n"; + echo "\n"; } echo "\n";