From 249130e58ddd20c5ad937f75e0e6cf3e4f6792a3 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Fri, 1 Nov 2019 15:03:57 +0300 Subject: implement app password checking / management UI --- classes/pref/prefs.php | 107 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 4 deletions(-) (limited to 'classes/pref/prefs.php') diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index d9482b966..76dc526ab 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -395,13 +395,29 @@ class Pref_Prefs extends Handler_Protected { print ""; print ""; # content pane - print "
"; - print_notice("You can create separate passwords for API clients. Using one is required if you enable OTP."); + if ($_SESSION["auth_module"] == "auth_internal") { + print "
"; + print_notice("You can create separate passwords for the API clients. Using one is required if you enable OTP."); - print "
"; # content pane + print "
"; + $this->appPasswordList(); + print "
"; + + print "
"; + + print " "; + + print ""; + + print "
"; # content pane + } print "
"; @@ -450,7 +466,7 @@ class Pref_Prefs extends Handler_Protected { } else { print_warning("You will need a compatible Authenticator to use this. Changing your password would automatically disable OTP."); - print_notice("You will also need to create a separate App password for API clients if you enable OTP."); + print_notice("You will need to use a separate password for the API clients if you enable OTP."); if (function_exists("imagecreatefromstring")) { print "

" . __("Scan the following code by the Authenticator application or copy the key manually:") . "

"; @@ -1221,4 +1237,87 @@ class Pref_Prefs extends Handler_Protected { } return ""; } + + private function appPasswordList() { + print "
"; + print "
" . + "" . __('Select') . ""; + print "
"; + print "
" . __('All') . "
"; + print "
" . __('None') . "
"; + print "
"; + print "
"; #toolbar + + print "
"; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + print ""; + + $sth = $this->pdo->prepare("SELECT id, title, created, last_used + FROM ttrss_app_passwords WHERE owner_uid = ?"); + $sth->execute([$_SESSION['uid']]); + + while ($row = $sth->fetch()) { + + $row_id = $row["id"]; + + print ""; + + print ""; + print ""; + + print ""; + + print ""; + + print ""; + } + + print "
".__("Description")."".__("Created")."".__("Last used")."
+ " . htmlspecialchars($row["title"]) . ""; + print make_local_datetime($row['created'], false); + print ""; + print make_local_datetime($row['last_used'], false); + print "
"; + print "
"; + } + + private function encryptAppPassword($password) { + $salt = substr(bin2hex(get_random_bytes(24)), 0, 24); + + return "SSHA-512:".hash('sha512', $salt . $password). ":$salt"; + } + + function deleteAppPassword() { + $ids = explode(",", clean($_REQUEST['ids'])); + $ids_qmarks = arr_qmarks($ids); + + $sth = $this->pdo->prepare("DELETE FROM ttrss_app_passwords WHERE id IN ($ids_qmarks) AND owner_uid = ?"); + $sth->execute(array_merge($ids, [$_SESSION['uid']])); + + $this->appPasswordList(); + } + + function generateAppPassword() { + $title = clean($_REQUEST['title']); + $new_password = make_password(16); + $new_password_hash = $this->encryptAppPassword($new_password); + + print_warning(T_sprintf("Generated password %s for %s. Please remember it for future reference.", $new_password, $title)); + + $sth = $this->pdo->prepare("INSERT INTO ttrss_app_passwords + (title, pwd_hash, service, created, owner_uid) + VALUES + (?, ?, ?, NOW(), ?)"); + + $sth->execute([$title, $new_password_hash, Auth_Base::AUTH_SERVICE_API, $_SESSION['uid']]); + + $this->appPasswordList(); + } } -- cgit v1.2.3