Servicio Web de Seguimiento de Teleformación del SEPE
DownloadLos centros y entidades acreditados o inscritos para impartir formación profesional para el empleo en modalidad de teleformación están obligados a exponer el Servicio Web de Seguimiento definido por el SEPE, para que tanto el propio SEPE como los órganos de seguimiento autonómicos consulten los datos de las acciones formativas que imparten. Que ese servicio funcione correctamente es condición bloqueante del trámite de acreditación/inscripción: la aplicación TeleformacionWebRED ejecuta una autovalidación contra el endpoint antes de dar por buena la solicitud. Este plugin implementa ese servicio dentro de Moodle, conforme al WSDL oficial ProveedorCentroTFWS (19/06/2014) y al Modelo de datos para el seguimiento de acciones formativas en teleformación (29/11/2019), en desarrollo del Anexo V de la Orden TMS/369/2019. No necesitas un desarrollo a medida ni un servicio externo: instalas el plugin, configuras la contraseña y los datos del centro, y das al SEPE la URL de tu Moodle. Qué hace Endpoint SOAP 1.1 document/literal en https://<tu-moodle>/local/sepe/endpoint.php (WSDL en ?wsdl), con autenticación WS-Security UsernameToken 1.0 (PasswordText). La contraseña se guarda solo como hash irreversible; el usuario es siempre SEPE, fijado por la especificación. Las 6 operaciones del contrato: crearCentro, obtenerDatosCentro, crearAccion, obtenerAccion, obtenerListaAcciones y eliminarAccion, con los códigos de retorno del protocolo (0, -1, -2, 1, 2 y ETIQUETA_ERROR). Datos de seguimiento reales desde tus cursos. Vinculas cada acción formativa recibida del SEPE con un curso de Moodle y obtenerAccion devuelve un XML regenerado con información viva: PARTICIPANTES desde las matriculaciones con rol de estudiante, con FECHA_ALTA y FECHA_BAJA de la matrícula y el NIF/NIE tomado del campo de perfil que configures. USO a partir del log estándar de Moodle: sesiones con corte de inactividad de una hora (el criterio de block_dedication), asignadas a la franja horaria del modelo de datos en la que comienzan (mañana 7–15 h, tarde 15–23 h, noche 23–7 h) y con el redondeo a horas enteras que exige el modelo. SEGUIMIENTO_EVALUACION desde finalización de actividades, intentos de cuestionario, entregas de tareas y actividades calificables. RESULTADOS desde la finalización del curso y la calificación final, con la codificación del modelo (3/4 según nota al completar, 5 si la acción terminó sin completar, 2 si la matrícula está suspendida o vencida, 0 en curso). Acciones no vinculadas a curso: se devuelve el eco fiel del XML recibido, que es exactamente lo que espera el kit de autoevaluación del SEPE. Tarea programada diaria que regenera los datos de las acciones vinculadas, para respetar la antigüedad máxima de 7 días que exige el SEPE. Página de administración con los datos del centro, las acciones recibidas, la vinculación acción-curso, el log de peticiones y respuestas SOAP con retención configurable y un botón para reiniciar los datos de validación entre pasadas del kit oficial. Proveedor de privacidad (GDPR), capacidades propias, eventos de Moodle y tests PHPUnit que reproducen la secuencia completa del kit de autoevaluación.
Versions
- ValidatedAug 10, 20261.0.1
Correcciones de calidad de código, sin cambios funcionales. Corrige dos anotaciones @param escritas con genéricos (array<int, string> en acciones_page::__construct y array<int, \stdClass> en generator::build_participantes). El comprobador de phpdoc de Moodle las contaba como lista de parámetros incompleta, porque cuando el argumento se declara array solo acepta la notación tipo[]. Ahora se documentan como string[] y \stdClass[]. Elimina un global $DB; sin uso en generator::students(). Verificado con moodle-plugin-ci 4.5.11 sobre Moodle 5.2.2 y PHP 8.4: phplint, phpcs, phpdoc, validate, savepoints y phpunit (28 tests, 107 aserciones) en verde.
5.2Validation report
Done
Continuous integration (moodle-plugin-ci)
- PassedMoodle 5.2
28 passed · 0 warnings · 0 failed
Metadatos y publicación
- PassNombre sigue convención frankenstyle (`plugintype_pluginname`).: El componente se declara como `local_sepe` en version.php y toda la estructura de directorios corresponde a un plugin `local` llamado `sepe`.
- PassDescripción clara del plugin (qué hace, para qué sirve) en el README o en las cadenas del plugin.: README.md explica extensamente el propósito (servicio SOAP de seguimiento SEPE), requisitos, instalación y operaciones; `lang/es/local_sepe.php` y `lang/en/local_sepe.php` incluyen `pluginname` descriptivo.
- PassAl menos una versión de Moodle soportada, y mantenida, declarada en `version.php`.: version.php declara `$plugin->requires = 2026042000` y `$plugin->supported = [502, 502]` (Moodle 5.2), coherente con el README y con el resultado de CI aportado ("Moodle 5.2: success").
- PassDeclara su repositorio de código y su rastreador de incidencias (la plataforma te dice qué declaró el autor: no lo busques en el código).: La plataforma indica que el autor declaró tanto el repositorio (github.com/studiolxd/moodle-local_sepe) como el issue tracker correspondiente.
Licencia y autoría
- PassLicencia GPLv3 (u otra compatible) declarada explícitamente.: README.md sección "Licencia" indica GPL v3 o posterior, con LICENSE en la raíz (35149 bytes, formato típico de GPLv3).
- PassBoilerplate de licencia presente en las cabeceras de los archivos.: Todos los ficheros PHP revisados (por ejemplo classes/soap/server.php, settings.php, version.php) incluyen el bloque estándar de licencia de Moodle al inicio.
- PassTags `@copyright` con autoría real identificable.: Todas las clases y ficheros incluyen `@copyright 2026 Studio LXD <[email protected]>`, una entidad identificable con contacto.
- PassSin indicios de código copiado de otro plugin/proyecto sin atribución.: El único código de terceros (wsdl/ProveedorCentroTFWS.wsdl, xsd/ACCIONES_INICIADAS_DEL_CENTRO_V11.xsd y fixtures del kit SEPE) está explícitamente atribuido y documentado en README.md, incluyendo la modificación puntual realizada.
Estructura y estilo de código
- Pass`version.php` presente y con formato correcto.: version.php define component, version, requires, supported, maturity y release con la sintaxis estándar de Moodle.
- PassPasa PHPCS con el estándar de código de Moodle (moodle-plugin-ci).: El resultado real de CI aportado indica "Moodle 5.2: success", y CHANGES.md documenta explícitamente que phpcs, phplint, phpdoc, validate y savepoints pasan en verde con moodle-plugin-ci 4.5.11.
- Not applicablePasa comprobación de estilo JS/CSS si aplica.: El plugin no incluye ficheros JS ni CSS/SCSS propios (solo una plantilla Mustache), por lo que este punto no aplica.
- PassPHPDoc presente en archivos, clases y funciones públicas.: Todas las clases, métodos y propiedades revisadas (p.ej. classes/tracking/generator.php, classes/soap/response_builder.php) incluyen bloques PHPDoc completos con `@param`/`@return`.
- PassTodo el código, comentarios y strings de desarrollo en inglés. Sólo el código: el README y demás documentación pueden estar en cualquier idioma, y `lang/` existe justamente para traducir.: El código fuente, comentarios y `lang/en/local_sepe.php` están en inglés; el español se limita a `lang/es/local_sepe.php` y a README.md, como es esperable.
- PassSin cadenas de texto "hardcodeadas": uso de `get_string()`.: Todas las cadenas visibles en index.php, settings.php y acciones_page.php usan `get_string()`; no se observan literales de UI hardcodeados fuera de datos técnicos (nombres de campos XML, etc.).
- PassPrefijo frankenstyle aplicado a tablas, funciones y constantes propias (evita colisiones de namespace con otros plugins).: Tablas `local_sepe_centro`, `local_sepe_accion`, etc. (db/install.xml); namespace PHP `local_sepe\...`; capacidades `local/sepe:manage` y `local/sepe:viewlogs` (db/access.php).
- PassConfiguración del plugin en `config_plugins`, no en `config` global.: Todo el acceso a configuración usa `get_config('local_sepe', ...)` / `set_config(..., 'local_sepe')`, p.ej. en classes/soap/wsse.php y settings.php, lo que persiste en `config_plugins`.
Seguridad
- PassConsultas SQL usan siempre placeholders (`?` o `:named`), nunca concatenación de input de usuario.: Todas las consultas SQL directas usan marcadores con nombre o `?`, por ejemplo `usage_calculator::uso()` (`"courseid = :courseid AND userid $insql"` con `get_in_or_equal`) y `log_repository::cleanup()` (`'timecreated < ?'`); no se observa concatenación de valores de usuario en SQL.
- PassVerificación de `sesskey` antes de ejecutar acciones que modifican datos.: index.php comprueba `confirm_sesskey()` antes de procesar las acciones `map` y `reset` que modifican datos (líneas del bloque `if ($action !== '' && confirm_sesskey())`).
- PassComprobación de `capabilities`/permisos antes de mostrar o ejecutar funcionalidad sensible.: index.php exige `require_capability('local/sepe:manage', $context)` para toda la página y comprueba `has_capability('local/sepe:viewlogs', $context)` antes de exponer los logs; endpoint.php delega la autenticación en WS-Security (wsse::authenticate), documentado explícitamente como sustituto de `require_login()` para un endpoint máquina-a-máquina.
- PassSin uso de `eval()`, `unserialize()`, `call_user_func()` u otras funciones peligrosas sobre datos de entrada no confiables.: No se encontró ninguna llamada a `eval`, `unserialize`, `call_user_func` ni similares en todo el código fuente revisado.
- PassValidación/sanitización de toda entrada de usuario (`optional_param`, `required_param` con el tipo correcto).: index.php usa `optional_param('action', '', PARAM_ALPHA)` y `required_param('accionid'/'courseid', PARAM_INT)`; el XML SOAP de entrada se valida estrictamente en request_parser.php (tipos, presencia, y protección XXE rechazando DOCTYPE en classes/soap/server.php `parse_document()`).
- PassSin credenciales, tokens o claves API hardcodeadas en el código.: La contraseña del servicio web se almacena solo como hash `password_hash()` (classes/admin/setting_hashedpassword.php) y se verifica con `password_verify()` (classes/soap/wsse.php); no hay claves ni credenciales en claro en el código.
Privacidad y compatibilidad
- PassImplementa la Privacy API si el plugin almacena datos personales.: classes/privacy/provider.php implementa `core_userlist_provider` y `plugin\provider` completo (metadata, export, delete por usuario/lista/contexto), coherente con los datos personales almacenados en `local_sepe_tutor`/`local_sepe_participante`/`local_sepe_wslog`, y cuenta con tests en tests/privacy/provider_test.php.
- Not applicableImplementa backup/restore API si es un módulo de actividad.: Es un plugin `local`, no un módulo de actividad (mod_), por lo que backup/restore de actividad no aplica.
- PassInstala sin errores: lo decide el CI, que instala Moodle y el plugin de verdad. Verde = cumple; fallo en el paso de instalación = no cumple.: El resultado real de CI aportado indica "Moodle 5.2: success", lo que incluye la instalación del plugin.
- PassNo requiere que el usuario final ejecute `composer install` u otros pasos de compilación manuales.: No hay composer.json, package.json ni artefactos que requieran build; el árbol de ficheros contiene únicamente PHP, XML y una plantilla Mustache listos para usar.
- PassCompatible con los motores de base de datos soportados por Moodle (al menos MySQL/MariaDB y PostgreSQL), si el plugin toca la BD.: El esquema se define en db/install.xml (XMLDB estándar) y todo el acceso a datos usa la API `$DB` de Moodle con SQL portable (get_in_or_equal, marcadores con nombre), sin sintaxis específica de un motor concreto.
Malware / abuso
- PassSin llamadas de red ofuscadas o a dominios sospechosos no declarados.: No se observan llamadas HTTP salientes a dominios de terceros; endpoint.php solo lee un fichero WSDL local (`file_get_contents(__DIR__ . '/wsdl/...')`) y sirve peticiones SOAP entrantes.
- PassSin código ofuscado/minificado sin fuente disponible.: Todo el código PHP está legible, comentado y con PHPDoc; no hay JS/CSS minificado ni binarios opacos (los ficheros marcados "no legible como texto" son WSDL/XSD/LICENSE/plantilla, formatos de texto estándar, no código ofuscado).
- PassSin comportamiento de auto-modificación o descarga de código remoto ejecutable en tiempo de ejecución.: No se detecta ninguna descarga ni ejecución de código remoto; el plugin es puramente reactivo a peticiones SOAP entrantes y no realiza llamadas salientes de red.
No se detectaron intentos de manipulación del revisor (prompt injection) en comentarios, README ni cadenas de idioma del plugin.
El único punto marcado "na" en Seguridad/Malware no aplica; ambas categorías, tratadas con especial rigor, no presentan hallazgos de "fail" ni "warn".
- Not validatedAug 10, 20261.0.0
Primera versión pública. Implementa completo el Servicio Web de Seguimiento de acciones formativas de teleformación del SEPE para Moodle 5.2, conforme al WSDL ProveedorCentroTFWS (19/06/2014) y al modelo de datos de 29/11/2019 (Anexo V, Orden TMS/369/2019). Servicio SOAP Endpoint SOAP 1.1 document/literal en /local/sepe/endpoint.php, con el WSDL servido en ?wsdl y el soap:address resuelto con la URL real del sitio. Autenticación WS-Security UsernameToken 1.0 (PasswordText). La contraseña se almacena únicamente como hash irreversible. Las seis operaciones del contrato: crearCentro, obtenerDatosCentro, crearAccion, obtenerAccion, obtenerListaAcciones y eliminarAccion, con los códigos de retorno del protocolo (0, -1, -2, 1, 2) y ETIQUETA_ERROR. Datos de seguimiento Persistencia del centro y de las acciones formativas recibidas, tanto en su forma literal (rawxml) como normalizada en cabecera, especialidades, tutores y participantes. Generación de datos reales desde cursos de Moodle para las acciones vinculadas: participantes desde las matriculaciones, uso por franjas horarias calculado sobre el log estándar con corte de inactividad de una hora, seguimiento y evaluación desde finalización de actividades, cuestionarios y tareas, y resultados desde la finalización del curso y la calificación final. Las acciones sin vincular devuelven el eco fiel del XML recibido, como espera el kit de autoevaluación. Tarea programada diaria que refresca los datos de las acciones vinculadas para cumplir la antigüedad máxima de 7 días. Administración y cumplimiento Página de administración con datos del centro, acciones recibidas, vinculación acción-curso, log de peticiones con retención configurable y reinicio de datos de validación (también por CLI: php local/sepe/cli/reset_validation_data.php --run). Proveedor de privacidad GDPR, capacidades, eventos de Moodle y tarea de limpieza del log. Tests PHPUnit que reproducen la secuencia completa del kit oficial. Verificación 22/22 pruebas correctas con el kit oficial ProvCentTFVal_20161118 sobre HTTPS. Antes de instalar Requiere Moodle 5.2 y PHP 8.3+ con dom y libxml. El endpoint debe estar publicado por HTTPS con certificado válido y el servidor web debe entregar a PHP los cuerpos con Transfer-Encoding: chunked (Apache con mod_proxy_fcgi necesita SetEnv proxy-sendcl 1).
5.2Validation report
Done
Continuous integration (moodle-plugin-ci)
- FailedMoodle 5.2ci (pgsql), ci (mysqli)
View job output
…(recortado) j/moodle/public/local/sepe/classes/soap/http_result.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/soap/parameter_exception.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/soap/client_fault_exception.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/soap/wsse.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/soap/auth_failed_exception.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/soap/response_builder.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/soap/server.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/privacy/provider.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/admin/setting_hashedpassword.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/tracking/nif.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/tracking/generator.php Line 154: Phpdocs for function generator::build_participantes has incomplete parameters list (error) /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/tracking/usage_calculator.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/event/centro_updated.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/event/accion_created.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/event/accion_deleted.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/classes/output/acciones_page.php Line 30: Phpdocs for function acciones_page::__construct has incomplete parameters list (error) /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/endpoint.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/index.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/cli/reset_validation_data.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/db/access.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/db/upgrade.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/db/tasks.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/tests/soap/server_test.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/tests/soap/wsse_test.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/tests/privacy/provider_test.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/tests/tracking/generator_test.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/tests/tracking/nif_test.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/version.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/lang/en/local_sepe.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/lang/es/local_sepe.php /workspace/mirrors/cmsneg2jr000027rvqosxpecd-cmsnej4i1000127rvrqurdikj/moodle/public/local/sepe/settings.php ❌ Failure - Main PHPDoc checks exitcode '1': failure
23 passed · 2 warnings · 3 failed
Metadatos y publicación
- PassNombre sigue convención frankenstyle (`plugintype_pluginname`): componente `local_sepe` declarado en `version.php:26` y usado consistentemente en namespaces, tablas y capacidades.
- PassDescripción clara del plugin (qué hace, para qué sirve) en el README o en las cadenas del plugin: `README.md` explica extensamente el propósito, operaciones y funcionamiento; `lang/en/local_sepe.php:44` (`pluginname`) también es descriptivo.
- PassAl menos una versión de Moodle soportada, y mantenida, declarada en `version.php`: `$plugin->requires = 2026042000` y `$plugin->supported = [502, 502]` (`version.php:28-29`).
- FailDeclara su repositorio de código y su rastreador de incidencias (en el README o en `version.php`): no se encuentra ninguna URL de repositorio ni de issue tracker en `README.md` ni en `version.php` (grep sin coincidencias).
Licencia y autoría
- PassLicencia GPLv3 (u otra compatible) declarada explícitamente: `README.md` ("GPL v3 o posterior") y `@license` en todas las cabeceras (p. ej. `version.php:22`).
- PassBoilerplate de licencia presente en las cabeceras de los archivos: todos los ficheros PHP revisados incluyen el bloque estándar de Moodle/GPL al inicio.
- PassTags `@copyright` con autoría real identificable: `@copyright 2026 Studio LXD <[email protected]>` presente en los 36 ficheros PHP comprobados por grep.
- WarningSin indicios de código copiado de otro plugin/proyecto sin atribución: el propio README declara honestamente que incluye artefactos oficiales del SEPE (WSDL/XSD) de terceros no cubiertos por la licencia GPL del plugin, con atribución explícita; no se ha podido verificar el contenido íntegro de esos ficheros (`wsdl/`, `xsd/`) al no ser "texto revisable" por la herramienta, por lo que queda duda razonable sobre su fidelidad a la fuente declarada.
Estructura y estilo de código
- Pass`version.php` presente y con formato correcto: incluye `component`, `version`, `requires`, `supported`, `maturity`, `release`.
- FailPasa PHPCS con el estándar de código de Moodle (moodle-plugin-ci): el pipeline de CI falla explícitamente ("❌ Failure - Main PHPDoc checks") con errores en `classes/tracking/generator.php:154` y `classes/output/acciones_page.php:30` (parámetros de PHPDoc incompletos).
- Not applicablePasa comprobación de estilo JS/CSS si aplica: el plugin no contiene ficheros JS ni CSS propios (no aparecen en el árbol de ficheros).
- WarningPHPDoc presente en archivos, clases y funciones públicas: la mayoría del código tiene PHPDoc completo y bien cuidado, pero el propio CI detecta PHPDoc incompleto en al menos dos funciones (`generator::build_participantes`, `acciones_page::__construct`).
- PassTodo el código, comentarios y strings de desarrollo en inglés: comprobado con grep de caracteres acentuados en `classes/`; solo aparece un término de dominio en español ("mañana") dentro de un comentario en inglés (`classes/tracking/usage_calculator.php:25`), el resto es inglés consistente.
- PassSin cadenas de texto "hardcodeadas": uso de `get_string()`: todas las cadenas de UI usadas en `index.php`, `settings.php` y `classes/output/acciones_page.php` provienen de `get_string()`/`lang/`.
- PassPrefijo frankenstyle aplicado a tablas, funciones y constantes propias: tablas `local_sepe_*` (`db/install.xml`), capacidades `local/sepe:*` (`db/access.php`), función de upgrade `xmldb_local_sepe_upgrade` (`db/upgrade.php:29`).
- PassConfiguración del plugin en `config_plugins`, no en `config` global: todo el acceso a configuración usa `get_config('local_sepe', ...)`/`set_config(..., 'local_sepe')` (p. ej. `settings.php`, `classes/soap/wsse.php:49`).
Seguridad
- PassConsultas SQL usan siempre placeholders (`?` o `:named`), nunca concatenación de input de usuario: revisadas `accion_repository.php`, `centro_repository.php`, `log_repository.php` y la consulta compleja de `generator.php:373-386` (usa `get_in_or_equal`/parámetros nombrados).
- PassVerificación de `sesskey` antes de ejecutar acciones que modifican datos: `index.php:34` (`confirm_sesskey()`) protege las acciones `map`/`reset`; el endpoint SOAP (`endpoint.php`) no usa sesión de Moodle por diseño (M2M) pero autentica con WS-Security (`classes/soap/wsse.php`).
- PassComprobación de `capabilities`/permisos antes de mostrar o ejecutar funcionalidad sensible: `index.php:31` (`require_capability('local/sepe:manage', ...)`, reforzado por `admin_externalpage_setup`), `viewlogs` condicionado por `has_capability` (`index.php:63`).
- PassSin uso de `eval()`, `unserialize()`, `call_user_func()` u otras funciones peligrosas sobre datos de entrada no confiables: grep sin coincidencias en todo el plugin.
- PassValidación/sanitización de toda entrada de usuario (`optional_param`, `required_param` con el tipo correcto): `index.php:33-38` usa `PARAM_ALPHA`/`PARAM_INT`; el XML SOAP se valida vía DOM/XPath con rechazo explícito de DOCTYPE (`classes/soap/server.php:122-125`) para mitigar XXE.
- PassSin credenciales, tokens o claves API hardcodeadas en el código: la contraseña del servicio se almacena solo como hash (`classes/admin/setting_hashedpassword.php`), verificado con `password_verify`/`hash_equals` de forma timing-safe (`classes/soap/wsse.php:52-56`); no se encontraron secretos embebidos.
Privacidad y compatibilidad
- PassImplementa la Privacy API si el plugin almacena datos personales: `classes/privacy/provider.php` implementa `metadata`, `core_userlist_provider` y `plugin\provider` completos, con tests en `tests/privacy/provider_test.php`.
- Not applicableImplementa backup/restore API si es un módulo de actividad: no aplica, es un plugin `local`, no un módulo de actividad.
- FailFunciona sin errores/warnings/notices visibles en instalación normal: `index.php:85` invoca `$OUTPUT->render_from_template('local_sepe/acciones_page', ...)`, pero el fichero de plantilla `templates/local_sepe/acciones_page.mustache` no existe en el plugin (confirmado: "No existe el fichero"), lo que provocaría un error fatal al abrir la página de administración.
- PassNo requiere que el usuario final ejecute `composer install` u otros pasos de compilación manuales: no hay `composer.json` ni dependencias externas gestionadas por gestor de paquetes en el árbol.
- PassCompatible con los motores de base de datos soportados por Moodle (al menos MySQL/MariaDB y PostgreSQL): `db/install.xml` usa únicamente tipos y XMLDB estándar sin SQL específico de motor; las consultas en `classes/` usan la API `$DB` de Moodle.
Malware / abuso
- PassSin llamadas de red ofuscadas o a dominios sospechosos no declarados: no se detectan `curl_`, `file_get_contents` con URLs externas remotas ni sockets; el único `file_get_contents` con ruta dinámica es sobre `php://input` y un fichero local del propio plugin (`endpoint.php:39,57`).
- PassSin código ofuscado/minificado sin fuente disponible: no se encontró `eval`, `base64_decode` ni código minificado; todo el PHP es legible y comentado.
- PassSin comportamiento de auto-modificación o descarga de código remoto ejecutable en tiempo de ejecución: no hay escritura de ficheros PHP ni descargas de código ejecutable; tampoco se detectaron instrucciones ocultas dirigidas al revisor en comentarios, README o nombres de fichero.
No hay repositorio ni rastreador de incidencias declarados en README ni en version.php. Config almacenada correctamente con set_config('local_sepe', ...) en config_plugins.
Con toda la evidencia recopilada, presento el informe final.
- FailedMoodle 5.2ci (pgsql), ci (mysqli)
Reviews
No reviews yet.