AraiFirebaseAuth.php

De SIU
Saltar a: navegación, buscar
  1. <?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;
        }
    }