Enable app-specific password authentication for API login

This commit is contained in:
Hypolite Petovan 2019-07-22 07:56:36 -04:00
parent 8cdc0172e7
commit cd257dc7e8
2 changed files with 17 additions and 9 deletions

View file

@ -236,7 +236,7 @@ function api_login(App $a)
if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) { if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) {
$record = $addon_auth['user_record']; $record = $addon_auth['user_record'];
} else { } else {
$user_id = User::authenticate(trim($user), trim($password)); $user_id = User::authenticate(trim($user), trim($password), true);
if ($user_id !== false) { if ($user_id !== false) {
$record = DBA::selectFirst('user', [], ['uid' => $user_id]); $record = DBA::selectFirst('user', [], ['uid' => $user_id]);
} }

View file

@ -17,6 +17,7 @@ use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Model\TwoFactor\AppSpecificPassword;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
@ -267,17 +268,18 @@ class User
/** /**
* Authenticate a user with a clear text password * Authenticate a user with a clear text password
* *
* @brief Authenticate a user with a clear text password * @brief Authenticate a user with a clear text password
* @param mixed $user_info * @param mixed $user_info
* @param string $password * @param string $password
* @param bool $third_party
* @return int|boolean * @return int|boolean
* @deprecated since version 3.6 * @deprecated since version 3.6
* @see User::getIdFromPasswordAuthentication() * @see User::getIdFromPasswordAuthentication()
*/ */
public static function authenticate($user_info, $password) public static function authenticate($user_info, $password, $third_party = false)
{ {
try { try {
return self::getIdFromPasswordAuthentication($user_info, $password); return self::getIdFromPasswordAuthentication($user_info, $password, $third_party);
} catch (Exception $ex) { } catch (Exception $ex) {
return false; return false;
} }
@ -287,16 +289,22 @@ class User
* Returns the user id associated with a successful password authentication * Returns the user id associated with a successful password authentication
* *
* @brief Authenticate a user with a clear text password * @brief Authenticate a user with a clear text password
* @param mixed $user_info * @param mixed $user_info
* @param string $password * @param string $password
* @param bool $third_party
* @return int User Id if authentication is successful * @return int User Id if authentication is successful
* @throws Exception * @throws Exception
*/ */
public static function getIdFromPasswordAuthentication($user_info, $password) public static function getIdFromPasswordAuthentication($user_info, $password, $third_party = false)
{ {
$user = self::getAuthenticationInfo($user_info); $user = self::getAuthenticationInfo($user_info);
if (strpos($user['password'], '$') === false) { if ($third_party && PConfig::get($user['uid'], '2fa', 'verified')) {
// Third-party apps can't verify two-factor authentication, we use app-specific passwords instead
if (AppSpecificPassword::authenticateUser($user['uid'], $password)) {
return $user['uid'];
}
} elseif (strpos($user['password'], '$') === false) {
//Legacy hash that has not been replaced by a new hash yet //Legacy hash that has not been replaced by a new hash yet
if (self::hashPasswordLegacy($password) === $user['password']) { if (self::hashPasswordLegacy($password) === $user['password']) {
self::updatePasswordHashed($user['uid'], self::hashPassword($password)); self::updatePasswordHashed($user['uid'], self::hashPassword($password));