Diferencia entre revisiones de «AraiFirebaseAuth.php»
| Línea 1: | Línea 1: | ||
<source lang="php"> | <source lang="php"> | ||
<?php | <?php | ||
| − | + | ||
| − | ?> | + | use SimpleSAML\Logger; |
| + | use SIU\AraiUsuarios; | ||
| + | use SIU\AraiUsuarios\IDP\Factory; | ||
| + | use SIU\AraiUsuarios\Core\UsuariosManager; | ||
| + | use SIU\AraiUsuarios\Entities\Usuario; | ||
| + | use SIU\AraiUsuarios\Error; | ||
| + | |||
| + | use SAML2\Utilities\Temporal; | ||
| + | |||
| + | /** | ||
| + | * Simple SQL authentication source | ||
| + | * | ||
| + | * Implementa la autenticación contra un servicio Google Firebase Auth | ||
| + | * | ||
| + | * | ||
| + | * | ||
| + | * @package simpleSAMLphp | ||
| + | * @version $Id$ | ||
| + | */ | ||
| + | class sspmod_arai_Auth_Source_AraiFirebaseAuth extends sspmod_arai_Auth_Source_AraiAuth | ||
| + | { | ||
| + | /** | ||
| + | * @inheritDoc | ||
| + | */ | ||
| + | public function __construct($info, $config) | ||
| + | { | ||
| + | assert('isset($config["firebase_uri"])'); | ||
| + | assert('isset($config["firebase_key"])'); | ||
| + | |||
| + | $this->firebase_uri = $config['firebase_uri']; | ||
| + | $this->firebase_key = $config['firebase_key']; | ||
| + | |||
| + | parent::__construct($info, $config); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * @inheritDoc | ||
| + | */ | ||
| + | protected function login($uid, $clave) | ||
| + | { | ||
| + | assert('is_string($uid)'); | ||
| + | assert('is_string($clave)'); | ||
| + | |||
| + | $contexto = ['usuario' => $uid]; | ||
| + | $uid = strtolower($uid); | ||
| + | |||
| + | try { | ||
| + | /* @var UsuariosManager $usuariosManager */ | ||
| + | $usuariosManager = Factory::getUsuariosManager(); | ||
| + | |||
| + | if (!$this->autenticarEnFirebase($uid, $clave)) { | ||
| + | throw new SimpleSAML\Error\Error('WRONGUSERPASS', new Exception("El usuario Firebase '$uid' ingresa usuario y/o clave incorrecta")); | ||
| + | } | ||
| + | |||
| + | // TODO: deberíamos permitir que la auth vía Firebase escoja si es por uid o email? | ||
| + | $this->loginSubject = $usuariosManager->getUsuarioByEmail($uid); | ||
| + | if (!$this->loginSubject) { | ||
| + | throw new SimpleSAML\Error\Error('WRONGUSERPASS', new Exception("El usuario 'mail=$uid' no existe")); | ||
| + | } | ||
| + | |||
| + | //Si autentica y esta vencida la cuenta se marca como bloqueado | ||
| + | $dt = new DateTime(); | ||
| + | $dt->setTimestamp(Temporal::getTime()); | ||
| + | |||
| + | $uid = $this->loginSubject->getUid(); | ||
| + | $this->validarCuentaExpirada($usuariosManager, $uid, $dt); | ||
| + | |||
| + | /** | ||
| + | * Se maneja de forma externa, no agregar nuevas cuestiones relacionadas a las claves del usuario | ||
| + | $this->validarPasswordVencido($usuariosManager, $uid, $dt); | ||
| + | $usuariosManager->anularPedidosCambioPasswordPrevios($uid); | ||
| + | */ | ||
| + | |||
| + | $attributes = $usuariosManager->getAtributosSAMLUsuario($this->loginSubject); | ||
| + | } catch (SIU\AraiUsuarios\Error $e) { | ||
| + | $contexto['error'] = $e->getMessage(); | ||
| + | Factory::getIdpLogger()->notice('Se ingresa un usuario y/o clave incorrecto', $contexto); | ||
| + | SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$e->getMessage()); | ||
| + | throw new SimpleSAML\Error\Error('WRONGUSERPASS', $e); | ||
| + | } catch (\Exception $e) { | ||
| + | $contexto['error'] = $e->getMessage(); | ||
| + | Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); | ||
| + | SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$e->getMessage()); | ||
| + | throw $e; | ||
| + | } | ||
| + | |||
| + | Factory::getIdpLogger()->info('Usuario realiza login correcto', $contexto); | ||
| + | SimpleSAML\Logger::info('arai:' . $this->authId . ': Attributes: ' . implode(',', array_keys($attributes))); | ||
| + | |||
| + | return $attributes; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * @param $uid | ||
| + | * @param $clave | ||
| + | * @return bool | ||
| + | * @throws \GuzzleHttp\Exception\GuzzleException | ||
| + | */ | ||
| + | private function autenticarEnFirebase($uid, $clave) | ||
| + | { | ||
| + | $status = false; | ||
| + | |||
| + | $key = $this->firebase_key; | ||
| + | |||
| + | $uri = $this->firebase_uri . $key; | ||
| + | |||
| + | $contexto = [ | ||
| + | 'firebase_user' => $uid, | ||
| + | 'firebase_key' => $key, | ||
| + | 'firebase_uri' => $uri, | ||
| + | ]; | ||
| + | |||
| + | $body = [ | ||
| + | 'email'=> $uid, | ||
| + | 'password'=> $clave, | ||
| + | 'returnSecureToken'=> true, | ||
| + | ]; | ||
| + | |||
| + | try { | ||
| + | $client = new GuzzleHttp\Client(); | ||
| + | |||
| + | $res = $client->request('POST', $uri, [ | ||
| + | 'json' => $body | ||
| + | ]); | ||
| + | |||
| + | $status = $res->getStatusCode() == 200; | ||
| + | } catch (\GuzzleHttp\Exception\RequestException $e) { | ||
| + | $msg = $e->getMessage(); | ||
| + | if ($e->hasResponse()) { | ||
| + | $msg = json_decode($e->getResponse()->getBody()->getContents()); | ||
| + | $msg = $msg->error->errors; | ||
| + | } | ||
| + | $contexto['error'] = $msg; | ||
| + | Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); | ||
| + | SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$msg); | ||
| + | } catch (\GuzzleHttp\Exception\ClientException $e) { | ||
| + | $msg = $e->getResponse()->getReasonPhrase(); | ||
| + | $contexto['error'] = $msg; | ||
| + | Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); | ||
| + | SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$msg); | ||
| + | } catch (Exception $e) { | ||
| + | $contexto['error'] = $e->getMessage(); | ||
| + | Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); | ||
| + | SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$e->getMessage()); | ||
| + | } | ||
| + | |||
| + | return $status; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
</source> | </source> | ||
Revisión del 12:07 7 abr 2025
<?php use SimpleSAML\Logger; use SIU\AraiUsuarios; use SIU\AraiUsuarios\IDP\Factory; use SIU\AraiUsuarios\Core\UsuariosManager; use SIU\AraiUsuarios\Entities\Usuario; use SIU\AraiUsuarios\Error; use SAML2\Utilities\Temporal; /** * Simple SQL authentication source * * Implementa la autenticación contra un servicio Google Firebase Auth * * * * @package simpleSAMLphp * @version $Id$ */ class sspmod_arai_Auth_Source_AraiFirebaseAuth extends sspmod_arai_Auth_Source_AraiAuth { /** * @inheritDoc */ public function __construct($info, $config) { assert('isset($config["firebase_uri"])'); assert('isset($config["firebase_key"])'); $this->firebase_uri = $config['firebase_uri']; $this->firebase_key = $config['firebase_key']; parent::__construct($info, $config); } /** * @inheritDoc */ protected function login($uid, $clave) { assert('is_string($uid)'); assert('is_string($clave)'); $contexto = ['usuario' => $uid]; $uid = strtolower($uid); try { /* @var UsuariosManager $usuariosManager */ $usuariosManager = Factory::getUsuariosManager(); if (!$this->autenticarEnFirebase($uid, $clave)) { throw new SimpleSAML\Error\Error('WRONGUSERPASS', new Exception("El usuario Firebase '$uid' ingresa usuario y/o clave incorrecta")); } // TODO: deberíamos permitir que la auth vía Firebase escoja si es por uid o email? $this->loginSubject = $usuariosManager->getUsuarioByEmail($uid); if (!$this->loginSubject) { throw new SimpleSAML\Error\Error('WRONGUSERPASS', new Exception("El usuario 'mail=$uid' no existe")); } //Si autentica y esta vencida la cuenta se marca como bloqueado $dt = new DateTime(); $dt->setTimestamp(Temporal::getTime()); $uid = $this->loginSubject->getUid(); $this->validarCuentaExpirada($usuariosManager, $uid, $dt); /** * Se maneja de forma externa, no agregar nuevas cuestiones relacionadas a las claves del usuario $this->validarPasswordVencido($usuariosManager, $uid, $dt); $usuariosManager->anularPedidosCambioPasswordPrevios($uid); */ $attributes = $usuariosManager->getAtributosSAMLUsuario($this->loginSubject); } catch (SIU\AraiUsuarios\Error $e) { $contexto['error'] = $e->getMessage(); Factory::getIdpLogger()->notice('Se ingresa un usuario y/o clave incorrecto', $contexto); SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$e->getMessage()); throw new SimpleSAML\Error\Error('WRONGUSERPASS', $e); } catch (\Exception $e) { $contexto['error'] = $e->getMessage(); Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$e->getMessage()); throw $e; } Factory::getIdpLogger()->info('Usuario realiza login correcto', $contexto); SimpleSAML\Logger::info('arai:' . $this->authId . ': Attributes: ' . implode(',', array_keys($attributes))); return $attributes; } /** * @param $uid * @param $clave * @return bool * @throws \GuzzleHttp\Exception\GuzzleException */ private function autenticarEnFirebase($uid, $clave) { $status = false; $key = $this->firebase_key; $uri = $this->firebase_uri . $key; $contexto = [ 'firebase_user' => $uid, 'firebase_key' => $key, 'firebase_uri' => $uri, ]; $body = [ 'email'=> $uid, 'password'=> $clave, 'returnSecureToken'=> true, ]; try { $client = new GuzzleHttp\Client(); $res = $client->request('POST', $uri, [ 'json' => $body ]); $status = $res->getStatusCode() == 200; } catch (\GuzzleHttp\Exception\RequestException $e) { $msg = $e->getMessage(); if ($e->hasResponse()) { $msg = json_decode($e->getResponse()->getBody()->getContents()); $msg = $msg->error->errors; } $contexto['error'] = $msg; Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$msg); } catch (\GuzzleHttp\Exception\ClientException $e) { $msg = $e->getResponse()->getReasonPhrase(); $contexto['error'] = $msg; Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$msg); } catch (Exception $e) { $contexto['error'] = $e->getMessage(); Factory::getIdpLogger()->notice('Se produjo un error al intentar validr un usuario y/o clave', $contexto); SimpleSAML\Logger::error('arai:' . $this->authId . ": ".$e->getMessage()); } return $status; } }
