Autor: ciberkaos

  • OSINT: qué revela un documento Word

    OSINT: qué revela un documento Word

    Archivo entregado por el profesor: comunicado_faro_norte.docx. Es un caso ficticio preparado para esta práctica. No difundas una lista de respuestas antes de que todos los grupos terminen.

    Situación

    El equipo de comunicación de una empresa ficticia, Faro Norte, va a publicar un documento Word. Antes de hacerlo, quiere saber qué información podría descubrir cualquier persona que descargue el archivo. Actuarás como analista y elaborarás un informe breve con pruebas y recomendaciones.

    Trabaja únicamente con el documento de la práctica o con archivos propios autorizados. No publiques nombres reales, rutas personales ni documentos de terceros en servicios de análisis en línea.

    Objetivos

    • Distinguir el contenido visible, las propiedades internas del documento y los datos del sistema de archivos.
    • Extraer propiedades con una interfaz gráfica y con ExifTool.
    • Inspeccionar las partes internas de un DOCX sin modificar el original.
    • Explicar qué conclusiones están demostradas y cuáles son solo hipótesis.
    • Comprobar qué información permanece tras preparar una copia para publicación.

    Material

    • Un equipo con Microsoft Word o LibreOffice Writer y acceso a terminal.
    • ExifTool instalado. Comprueba con exiftool -ver. Si no está disponible, realiza los pasos de Word/LibreOffice y la inspección del DOCX; deja constancia de ello.
    • El archivo comunicado_faro_norte.docx, facilitado junto a este enunciado. El documento y las identidades que figuran en él son ficticios.

    Fase 1. Preparar el archivo y leer lo visible (10 minutos)

    1. Descarga comunicado_faro_norte.docx. Conserva este archivo sin abrirlo en un editor que guarde automáticamente.
    2. Duplica el archivo y llama a la copia comunicado_faro_norte_copia.docx. Analiza la copia; conserva el archivo entregado para poder comparar al final. Si usas una aplicación con guardado automático, desactívalo para este caso o trabaja siempre sobre otra copia.
    3. Abre la copia en Word o LibreOffice y anota únicamente lo que cualquiera puede ver al leer el documento: título, lugar, fecha, actividades y correo de contacto. Cierra sin guardar.
    4. Explica por qué los datos visibles no equivalen a los metadatos. Formula dos preguntas que crees que el documento podría responder sin que la información aparezca en la página.

    Evidencia 1: captura del comunicado y tabla con cinco datos visibles. Todos los nombres y lugares pertenecen al caso ficticio.

    Fase 2. Observar antes de extraer (5 minutos)

    1. Apunta el nombre, tamaño y extensión de la copia.
    2. Anota la fecha de modificación que muestra el explorador de archivos.
    3. Abre el documento y localiza su panel de propiedades: Archivo → Información → Propiedades en Word, o Archivo → Propiedades en LibreOffice. Registra los campos que aparezcan.
    4. Responde: ¿la fecha que muestra el sistema operativo pertenece necesariamente al contenido original? Justifica tu respuesta pensando en la copia que acabas de hacer.

    Evidencia 2: tabla con las propiedades visibles y su procedencia (explorador o editor).

    Fase 3. Leer metadatos con ExifTool (10 minutos)

    Abre una terminal en la carpeta del archivo. Ejecuta:

    exiftool -a -G1 -s comunicado_faro_norte_copia.docx

    En Windows PowerShell, si ExifTool no está en PATH, usa la ruta del ejecutable y del archivo entre comillas:

    & "C:\ruta\a\exiftool.exe" -a -G1 -s "C:\ruta\al\comunicado_faro_norte_copia.docx"

    Anota, solo si existen, Creator, LastModifiedBy, Title, Subject, Keywords, CreateDate, ModifyDate, RevisionNumber, Company, Manager, FileSize, FileType y FileModifyDate. Los nombres exactos pueden variar. No inventes campos ausentes. El prefijo entre corchetes indica el grupo de cada dato.

    Evidencia 3: captura o salida copiada del comando y una tabla:

    CampoValor encontradoGrupo / fuente¿Dato introducido, generado o incierto?

    Pregunta: compara las fechas internas con FileModifyDate. ¿Por qué podrían diferir?

    Fase 4. Examinar el interior del DOCX (15 minutos)

    Un DOCX es un paquete de archivos. Inspecciona una copia adicional sin sobrescribir el documento de trabajo.

    Opción gráfica, válida para Windows, macOS y Linux: duplica el .docx, cambia la extensión de esa copia a .zip y ábrela con un descompresor. Si el sistema pregunta si deseas cambiar la extensión, acepta. Abre estos archivos como texto (no ejecutes ningún contenido):

    • docProps/core.xml: propiedades principales, como creador, título y fechas, si están presentes.
    • docProps/app.xml: propiedades de aplicación, como el programa o estadísticas, cuando existen.
    • word/document.xml: texto del documento en formato XML; su lectura puede resultar incómoda porque el texto está dividido en elementos.

    Opción terminal en Linux/macOS:

    unzip -l comunicado_faro_norte_copia.docx
    unzip -p comunicado_faro_norte_copia.docx docProps/core.xml
    unzip -p comunicado_faro_norte_copia.docx docProps/app.xml

    En Windows puedes usar la opción gráfica; no necesitas instalar comandos adicionales.

    Evidencia 4: nombres de al menos cinco entradas del paquete y dos valores concretos encontrados en core.xml o app.xml. Si un archivo no existe, registra esa ausencia.

    Preguntas: ¿qué datos de ExifTool puedes localizar también en XML? ¿Qué datos proceden del sistema de archivos y no están en esos XML? Localiza también, si aparecen, propiedades que apunten a un proyecto o a personas que no se mencionan en el texto visible. ¿Encuentras alguna información que no se vea al leer el comunicado?

    Fase 5. Construir un informe OSINT (15 minutos)

    Rellena esta tabla. Usa «No consta» si un dato no aparece; «Hipótesis» si depende de una interpretación.

    AfirmaciónEvidencia exacta y ubicaciónGrado de confianzaPosible explicación alternativa
    El documento contiene un título interno
    Una persona concreta lo redactó
    Se editó después de crearlo
    Se utilizó un programa determinado

    Después responde en 100–150 palabras: ¿qué podría aprender un tercero que solo recibiese este DOCX? ¿Qué afirmaciones no puedes demostrar con los metadatos? Recuerda que el campo «Autor» puede configurarse manualmente o conservarse de una plantilla y no identifica necesariamente a quien escribió el texto.

    Fase 6. Reducir exposición y volver a comprobar (10–15 minutos)

    1. Conserva intacto el original. Crea comunicado_faro_norte_publicacion.docx.
    2. En Word, si está disponible, utiliza Archivo → Información → Comprobar si hay problemas → Inspeccionar documento; revisa las categorías ofrecidas y elimina de la copia las propiedades personales que decidas retirar. En LibreOffice, revisa Archivo → Propiedades y las opciones de eliminación de información personal al guardar disponibles en tu versión. Anota exactamente qué hiciste.
    3. Repite el comando de la fase 3 para la copia de publicación. Vuelve a examinar docProps/core.xml en esa copia.
    4. Compara antes y después. No des por hecho que todos los campos desaparecieron. Verifica también que el contenido que se pretende publicar sigue presente.
    Campo o contenidoAntesDespués¿Permanece?
    Autor
    Último editor
    Fechas internas
    Título
    Texto visible

    Conclusión: redacta tres medidas concretas que recomendarías antes de publicar documentos de tu centro o empresa.

    Ampliación opcional: formato DOC antiguo

    Si el profesor proporciona un .doc autorizado, repite solo las fases 2, 3 y 5. El formato .doc es binario: no intentes abrirlo como ZIP ni esperes encontrar docProps/core.xml. Compara qué propiedades puede recuperar ExifTool en cada formato y describe los límites de la comparación.

    Entrega

    Sube un ZIP con:

    1. README.md con objetivo, entorno utilizado, pasos realizados, tablas completadas, respuestas y conclusión.
    2. evidencias/ con capturas o salidas de terminal legibles, sin información personal real.
    3. El DOCX ficticio entregado y la copia preparada para publicación. No incluyas otros archivos personales.

    El README debe permitir que otra persona repita la práctica. Identifica cada captura en el texto. No se evaluará encontrar un número determinado de metadatos: algunos dependen del editor, la configuración y cómo se creó el archivo.

  • PRIMEROS PASOS CON ARDUINO Y WOKWI

    PRIMEROS PASOS CON ARDUINO Y WOKWI

    1. Presentación

    En este proyecto aprenderás los fundamentos de Arduino utilizando Wokwi, un simulador electrónico que funciona directamente desde el navegador. Durante la primera parte no necesitarás instalar Arduino IDE ni disponer de una placa física.

    Realizarás varios ejercicios guiados y resueltos. Deberás reproducirlos, comprobar su funcionamiento, introducir pequeñas modificaciones y documentar el trabajo realizado.

    En la última parte trasladarás uno de los circuitos a un Arduino real.

    No basta con copiar el código. Debes montar cada circuito, ejecutarlo, observar qué sucede y explicar con tus palabras cómo funciona.


    2. Objetivos

    Al terminar el proyecto serás capaz de:

    • Crear y guardar proyectos en Wokwi.
    • Reconocer las partes principales de una placa Arduino Uno.
    • Comprender la función de setup() y loop().
    • Configurar pines digitales como entradas o salidas.
    • Encender y apagar LED.
    • Utilizar pausas con delay().
    • Enviar información al monitor serie.
    • Leer el estado de un pulsador.
    • Construir un circuito sencillo en una protoboard.
    • Documentar una práctica técnica en formato Markdown.

    3. Herramientas necesarias

    Parte simulada

    • Ordenador con navegador web.
    • Cuenta de Wokwi.
    • Acceso a https://wokwi.com/.
    • Editor de Markdown utilizado en clase.

    Parte física final

    • Arduino Uno o placa compatible.
    • Cable USB.
    • Protoboard.
    • Un LED rojo, uno amarillo y uno verde.
    • Tres resistencias de 220 Ω o 330 Ω.
    • Un pulsador.
    • Cables de conexión.
    • Un equipo preparado por el profesor con Arduino IDE o Arduino Cloud Agent.

    4. Normas de trabajo

    Para cada ejercicio debes:

    1. Crear o duplicar un proyecto en Wokwi.
    2. Montar el circuito indicado.
    3. Copiar y ejecutar el código proporcionado.
    4. Abrir el monitor serie cuando se solicite.
    5. Comprobar el resultado.
    6. Realizar la modificación propuesta.
    7. Guardar el enlace del proyecto.
    8. Añadir a la documentación una captura y una explicación personal.

    En la documentación no se aceptarán explicaciones como «funciona bien» o «enciende el LED». Debes indicar qué elementos intervienen, qué instrucciones se ejecutan y cuál es el resultado observado.


    Parte I. Ejercicios guiados y resueltos en Wokwi

    Ejercicio 1. Hola, Arduino: uso del monitor serie

    Objetivo

    Aprender a enviar mensajes desde Arduino al ordenador mediante la comunicación serie.

    Componentes

    • Arduino Uno.

    No es necesario añadir componentes externos.

    Esquema visual

    En este ejercicio no existe cableado externo: la salida se observa en el monitor serie.

    flowchart LR
        A["Arduino Uno"] -->|"USB / comunicación serie a 9600 baudios"| M["Monitor serie de Wokwi"]
        M --> R["Mensajes y resultados"]

    Preparación en Wokwi

    1. Entra en https://wokwi.com/.
    2. Selecciona Start from Scratch.
    3. Elige Arduino Uno.
    4. Abre el archivo sketch.ino.
    5. Sustituye su contenido por el siguiente código.

    Código resuelto

    void setup() {
      Serial.begin(9600);
      Serial.println("Arduino iniciado correctamente");
    }
    
    void loop() {
      Serial.println("El programa sigue funcionando");
      delay(1000);
    }

    Explicación

    • Serial.begin(9600) inicia la comunicación serie a 9600 bits por segundo.
    • Serial.println() envía un texto y añade un salto de línea.
    • El mensaje incluido en setup() aparece una sola vez.
    • El mensaje incluido en loop() se repite cada segundo.
    • delay(1000) detiene el programa durante 1000 milisegundos.

    Comprobación

    Inicia la simulación. La consola o monitor serie debería mostrar:

    Arduino iniciado correctamente
    El programa sigue funcionando
    El programa sigue funcionando
    El programa sigue funcionando

    Modificación obligatoria

    Modifica el programa para que:

    • Muestre tu nombre al comenzar.
    • Muestre el texto Han pasado dos segundos cada dos segundos.

    Documentación

    Incluye una captura del monitor serie y explica por qué el primer mensaje aparece una sola vez y el segundo se repite.


    Ejercicio 2. LED integrado intermitente

    Objetivo

    Controlar una salida digital utilizando el LED integrado de Arduino Uno.

    Componentes

    • Arduino Uno.
    • LED integrado de la placa, conectado internamente al pin 13.

    Esquema visual

    flowchart LR
        A["Arduino Uno"] --> P["Pin digital 13"]
        P --> L["LED integrado L"]
        A -.->|"USB"| M["Monitor serie"]

    El LED marcado como L ya está montado en la placa. No debes añadir cables ni componentes.

    Código resuelto

    const int LED = 13;
    
    void setup() {
      pinMode(LED, OUTPUT);
      Serial.begin(9600);
      Serial.println("Prueba del LED iniciada");
    }
    
    void loop() {
      digitalWrite(LED, HIGH);
      Serial.println("LED encendido");
      delay(1000);
    
      digitalWrite(LED, LOW);
      Serial.println("LED apagado");
      delay(1000);
    }

    Explicación

    • const int LED = 13 asigna un nombre al número del pin.
    • pinMode(LED, OUTPUT) configura el pin como salida.
    • digitalWrite(LED, HIGH) activa el pin y enciende el LED.
    • digitalWrite(LED, LOW) desactiva el pin y apaga el LED.
    • Los mensajes permiten relacionar el estado físico del LED con la ejecución del programa.

    Modificación obligatoria

    Consigue que el LED:

    1. Permanezca encendido durante dos segundos.
    2. Permanezca apagado durante medio segundo.
    3. Muestre los estados correspondientes en el monitor serie.

    Preguntas

    1. ¿Para qué sirve pinMode()?
    2. ¿Qué diferencia hay entre HIGH y LOW?
    3. ¿Cuántas veces se ejecuta setup()?
    4. ¿Cuántas veces se ejecuta loop()?

    Ejercicio 3. Conexión de un LED externo

    Objetivo

    Aprender a conectar un LED externo y una resistencia a Arduino.

    Componentes

    • Arduino Uno.
    • Un LED rojo.
    • Una resistencia de 220 Ω o 330 Ω.
    • Cables.

    Conexiones

    ElementoConexión
    Pin 8 de ArduinoResistencia
    ResistenciaPata larga del LED, ánodo
    Pata corta del LED, cátodoGND

    La resistencia limita la corriente que atraviesa el LED y ayuda a evitar que se dañe.

    Esquema visual

    flowchart LR
        D8["Arduino D8"] --> R["Resistencia 220–330 Ω"]
        R --> A["Ánodo + · pata larga"]
        A --> L["LED rojo"]
        L --> C["Cátodo − · pata corta"]
        C --> G["Arduino GND"]
        USB["Conexión USB"] -.-> M["Monitor serie"]

    Recorrido de la corriente: D8 → resistencia → ánodo del LED → cátodo → GND.

    Código resuelto

    const int LED_ROJO = 8;
    int numeroParpadeo = 0;
    
    void setup() {
      pinMode(LED_ROJO, OUTPUT);
      Serial.begin(9600);
      Serial.println("LED externo preparado");
    }
    
    void loop() {
      numeroParpadeo++;
    
      digitalWrite(LED_ROJO, HIGH);
      Serial.print("Parpadeo numero: ");
      Serial.println(numeroParpadeo);
      delay(500);
    
      digitalWrite(LED_ROJO, LOW);
      delay(500);
    }

    Explicación

    Serial.print() escribe sin realizar un salto de línea. A continuación, Serial.println(numeroParpadeo) muestra el valor y termina la línea. De esta manera, texto y número aparecen juntos.

    Resultado esperado

    LED externo preparado
    Parpadeo numero: 1
    Parpadeo numero: 2
    Parpadeo numero: 3

    Modificación obligatoria

    Conecta el LED al pin 7, adapta el programa y haz que parpadee cada 250 milisegundos.

    Preguntas

    1. ¿Por qué se utiliza una resistencia?
    2. ¿Qué ocurriría si cambias el montaje al pin 7 pero no modificas el código?
    3. ¿Para qué sirve la variable numeroParpadeo?

    Ejercicio 4. Semáforo sencillo

    Objetivo

    Controlar varias salidas digitales y crear una secuencia.

    Componentes

    • Arduino Uno.
    • Un LED rojo.
    • Un LED amarillo.
    • Un LED verde.
    • Tres resistencias de 220 Ω o 330 Ω.

    Conexiones

    LEDPin de ArduinoConexión restante
    Rojo10Resistencia y GND
    Amarillo9Resistencia y GND
    Verde8Resistencia y GND

    Cada LED debe disponer de su propia resistencia.

    Esquema visual

    Los tres puntos GND representan la misma conexión de tierra de Arduino. Puedes unir los tres cátodos a la línea negativa de la protoboard y conectar esa línea a un pin GND de la placa.

    flowchart LR
        D10["D10"] --> RR["Resistencia"] --> LR["LED rojo"] --> G1["GND"]
        D9["D9"] --> RA["Resistencia"] --> LA["LED amarillo"] --> G2["GND"]
        D8["D8"] --> RV["Resistencia"] --> LV["LED verde"] --> G3["GND"]

    Código resuelto

    const int LED_ROJO = 10;
    const int LED_AMARILLO = 9;
    const int LED_VERDE = 8;
    
    void setup() {
      pinMode(LED_ROJO, OUTPUT);
      pinMode(LED_AMARILLO, OUTPUT);
      pinMode(LED_VERDE, OUTPUT);
    
      Serial.begin(9600);
      Serial.println("Semaforo iniciado");
    }
    
    void loop() {
      digitalWrite(LED_ROJO, HIGH);
      digitalWrite(LED_AMARILLO, LOW);
      digitalWrite(LED_VERDE, LOW);
      Serial.println("ROJO: detenerse");
      delay(3000);
    
      digitalWrite(LED_ROJO, LOW);
      digitalWrite(LED_VERDE, HIGH);
      Serial.println("VERDE: avanzar");
      delay(3000);
    
      digitalWrite(LED_VERDE, LOW);
      digitalWrite(LED_AMARILLO, HIGH);
      Serial.println("AMARILLO: precaucion");
      delay(1000);
    }

    Comprobación

    Observa que solamente debe permanecer encendido un LED en cada momento. Comprueba que el monitor serie muestra el mismo estado que representa el circuito.

    Modificación obligatoria

    Cambia los tiempos para que:

    • El rojo dure cuatro segundos.
    • El verde dure cinco segundos.
    • El amarillo dure dos segundos.

    Añade antes de cada cambio el mensaje Cambiando estado del semaforo.

    Preguntas

    1. ¿Por qué se declaran tres constantes diferentes?
    2. ¿Qué LED se enciende después del rojo?
    3. ¿Cuánto dura una secuencia completa tras realizar la modificación?
    4. ¿Por qué conviene mostrar el estado en el monitor serie?

    Ejercicio 5. Pulsador y monitor serie

    Objetivo

    Leer una entrada digital y mostrar su estado en el monitor serie.

    Componentes

    • Arduino Uno.
    • Un pulsador.
    • Un LED.
    • Una resistencia para el LED.

    Conexiones

    ElementoConexión
    Una patilla del pulsadorPin 2
    Patilla opuesta del pulsadorGND
    Pin 8Resistencia y ánodo del LED
    Cátodo del LEDGND

    Se utilizará la resistencia interna de Arduino mediante INPUT_PULLUP. Por ello, el pulsador tendrá lógica invertida:

    • Sin pulsar: HIGH.
    • Pulsado: LOW.

    Esquema visual

    flowchart LR
        D2["Arduino D2 · INPUT_PULLUP"] --> B["Pulsador"] --> G1["GND"]
        D8["Arduino D8 · OUTPUT"] --> R["Resistencia 220–330 Ω"]
        R --> A["Ánodo + del LED"] --> L["LED"] --> C["Cátodo −"] --> G2["GND"]

    El pulsador se conecta entre D2 y GND. No necesita una resistencia externa porque el programa activa la resistencia interna con INPUT_PULLUP.

    Código resuelto

    const int PULSADOR = 2;
    const int LED = 8;
    
    void setup() {
      pinMode(PULSADOR, INPUT_PULLUP);
      pinMode(LED, OUTPUT);
    
      Serial.begin(9600);
      Serial.println("Sistema preparado");
    }
    
    void loop() {
      int estadoPulsador = digitalRead(PULSADOR);
    
      if (estadoPulsador == LOW) {
        digitalWrite(LED, HIGH);
        Serial.println("Pulsador presionado - LED encendido");
      } else {
        digitalWrite(LED, LOW);
        Serial.println("Pulsador libre - LED apagado");
      }
    
      delay(200);
    }

    Explicación

    • INPUT_PULLUP configura el pin como entrada y activa una resistencia interna.
    • digitalRead() lee el estado del pin.
    • La estructura if permite tomar una decisión.
    • Cuando se pulsa, el estado leído es LOW y el LED se enciende.

    Modificación obligatoria

    Modifica únicamente los textos para que el monitor serie muestre:

    • ALARMA ACTIVADA al pulsar.
    • Sistema en espera al soltar.

    Después cambia el LED del pin 8 al pin 6, tanto en el circuito como en el programa.

    Preguntas

    1. ¿Qué valor devuelve el pulsador cuando está presionado?
    2. ¿Por qué en este montaje se considera pulsado cuando devuelve LOW?
    3. ¿Qué estructura del código permite decidir si el LED se enciende?

    Parte II. Implementación final en Arduino real

    Reto final: semáforo físico con diagnóstico serie

    En esta parte trasladarás el ejercicio 4 a un Arduino real. Es el único ejercicio del proyecto que debe implementarse físicamente.

    Esquema de referencia para el montaje físico

       
    flowchart LR
        D10["D10"] --> R1["220–330 Ω"] --> RO["LED rojo"] --> G["Línea GND de la protoboard"]
        D9["D9"] --> R2["220–330 Ω"] --> AM["LED amarillo"] --> G
        D8["D8"] --> R3["220–330 Ω"] --> VE["LED verde"] --> G
        G --> AG["Arduino GND"]
        AU["Arduino Uno"] -.->|"USB"| PC["Arduino IDE y monitor serie"]

    Antes de conectar el USB, comprueba que la pata larga de cada LED queda orientada hacia su resistencia y la pata corta hacia GND.

    Trabajo que debes realizar

    1. Recupera tu proyecto del semáforo en Wokwi.
    2. Comprueba que la simulación funciona correctamente.
    3. Reúne los componentes necesarios.
    4. Desconecta la placa del USB mientras realizas el montaje.
    5. Conecta los tres LED, cada uno con su propia resistencia.
    6. Revisa la polaridad de los LED.
    7. Solicita al profesor la revisión del circuito antes de alimentarlo.
    8. Conecta Arduino al ordenador.
    9. Abre el código con la herramienta indicada por el profesor.
    10. Selecciona la placa y el puerto correspondientes.
    11. Carga el programa.
    12. Abre el monitor serie a 9600 baudios.
    13. Comprueba que los LED y los mensajes siguen la misma secuencia.

    Requisitos mínimos

    • Los tres LED deben funcionar.
    • Nunca deben encenderse los tres a la vez.
    • Cada LED debe utilizar una resistencia.
    • El monitor serie debe indicar el estado actual.
    • El montaje físico debe corresponder con los pines declarados en el código.

    Pequeña adaptación obligatoria

    En el Arduino real, cambia la secuencia para que:

    • Rojo: 5 segundos.
    • Verde: 4 segundos.
    • Amarillo: 2 segundos.

    El monitor serie deberá mostrar también la duración de cada estado, por ejemplo:

    ROJO: detenerse durante 5 segundos
    VERDE: avanzar durante 4 segundos
    AMARILLO: precaucion durante 2 segundos

    Evidencias necesarias

    • Fotografía general del montaje real.
    • Fotografía donde puedan reconocerse los pines utilizados.
    • Captura del monitor serie.
    • Código final.
    • Explicación de las diferencias encontradas entre Wokwi y el montaje físico.
    • Breve descripción de cualquier error y de cómo se solucionó.

    Seguridad y buenas prácticas

    • No cambies conexiones con la placa alimentada.
    • No conectes un LED directamente sin resistencia.
    • Comprueba la polaridad antes de encender.
    • No fuerces los conectores.
    • Si el circuito se calienta o se comporta de forma extraña, desconecta el USB y avisa al profesor.

    Parte III. Documentación y entrega

    Formato de entrega

    La documentación se entregará en un archivo llamado:

    README.md

    Se redactará en Markdown con el editor utilizado en clase. Además del archivo, se entregará una carpeta img que contenga las capturas y fotografías.

    La estructura recomendada es:

    proyecto-arduino/
    ├── README.md
    └── img/
        ├── ejercicio1-monitor-serie.png
        ├── ejercicio2-led-integrado.png
        ├── ejercicio3-led-externo.png
        ├── ejercicio4-semaforo.png
        ├── ejercicio5-pulsador.png
        └── semaforo-real.jpg

    Estructura obligatoria del README

    # Proyecto de iniciación a Arduino
    
    ## Datos del alumno
    
    - Nombre:
    - Grupo:
    - Fecha:
    
    ## Introducción
    
    Explicación breve del objetivo del proyecto.
    
    ## Ejercicio 1. Monitor serie
    
    ### Montaje y funcionamiento
    
    Explicación personal.
    
    ### Código
    
    ```cpp
    // Código utilizado
    ```
    
    ### Resultado
    
    ![Monitor serie](img/ejercicio1-monitor-serie.png)
    
    ### Modificación realizada
    
    Explicación y resultado.
    
    ### Respuestas
    
    Respuestas a las preguntas del ejercicio.
    
    ## Ejercicio 2. LED integrado
    
    Repetir la misma organización.
    
    ## Ejercicio 3. LED externo
    
    Repetir la misma organización.
    
    ## Ejercicio 4. Semáforo
    
    Repetir la misma organización.
    
    ## Ejercicio 5. Pulsador
    
    Repetir la misma organización.
    
    ## Implementación en Arduino real
    
    Descripción, código, fotografías y problemas encontrados.
    
    ## Conclusiones
    
    Qué has aprendido y qué parte te ha resultado más difícil.
    
    ## Enlaces a los proyectos de Wokwi
    
    - Ejercicio 1:
    - Ejercicio 2:
    - Ejercicio 3:
    - Ejercicio 4:
    - Ejercicio 5:

    Para evitar problemas al incluir bloques de código dentro del README, utiliza tres acentos graves antes y después del código y escribe cpp junto a los tres primeros.

    Requisitos de la documentación

    El README.md debe contener:

    • Portada o título.
    • Datos del alumno.
    • Índice.
    • Explicación de cada ejercicio con palabras propias.
    • Código correctamente presentado en bloques cpp.
    • Una captura de cada simulación.
    • Capturas del monitor serie.
    • Enlaces a los proyectos de Wokwi.
    • Respuestas a todas las preguntas.
    • Evidencias del montaje real.
    • Problemas encontrados y soluciones aplicadas.
    • Conclusión personal.

    Penalizaciones

    • No entregar enlaces funcionales de Wokwi.
    • No incluir las capturas solicitadas.
    • Presentar código sin explicar su funcionamiento.
    • Copiar explicaciones de otras personas o generadas automáticamente sin revisarlas.
    • Conectar físicamente LED sin resistencia.
    • Entregar un documento distinto de README.md sin autorización.

    6. Lista de comprobación antes de entregar

    • He completado los cinco ejercicios de Wokwi.
    • He realizado todas las modificaciones obligatorias.
    • He probado el monitor serie.
    • He respondido las preguntas con mis palabras.
    • Los enlaces de Wokwi se pueden abrir.
    • He construido y probado el semáforo real.
    • He incluido el código en bloques Markdown.
    • Las imágenes se encuentran dentro de la carpeta img.
    • Todas las imágenes aparecen correctamente en el README.md.
    • He escrito una conclusión personal.
    • El archivo principal se llama exactamente README.md.

    7. Ampliación voluntaria

    Si terminas antes, modifica el semáforo de Wokwi para que el LED amarillo parpadee tres veces antes de encenderse el rojo. El monitor serie deberá informar de cada parpadeo.

    Documenta la ampliación indicando qué instrucciones has añadido y por qué.

  • OSINT: Operación Atlas

    OSINT: Operación Atlas

    Reconocimiento pasivo de dominios desde terminal

    Documentación de apoyo: Reconocimiento de dominios por terminal y scripting


    1. Introducción

    Una organización ficticia llamada Atlas Digital está revisando la información que su infraestructura publica en Internet. Durante los últimos años ha creado páginas web, aplicaciones, servicios de correo y entornos de pruebas, pero no dispone de un inventario actualizado.

    El equipo de seguridad necesita conocer su superficie externa visible mediante fuentes públicas antes de realizar una auditoría más profunda.

    Tu misión será actuar como analista OSINT. Utilizarás la terminal de Linux para descubrir subdominios, resolver direcciones IP, consultar información pública sobre esas direcciones y automatizar parte del proceso mediante un script en Bash.

    El objetivo no consiste únicamente en ejecutar comandos. Tendrás que interpretar, relacionar y documentar los resultados.


    2. Objetivos de aprendizaje

    Al finalizar el reto deberás ser capaz de:

    • Explicar qué es el reconocimiento OSINT pasivo.
    • Utilizar herramientas desde una terminal Linux.
    • Enumerar subdominios con Amass y Subfinder.
    • guardar, ordenar, combinar y filtrar resultados.
    • Resolver nombres de dominio y obtener sus direcciones IP.
    • Consultar información WHOIS y datos aproximados de geolocalización.
    • Procesar respuestas JSON con curl y jq.
    • Crear un script Bash sencillo para automatizar el análisis.
    • Diferenciar entre un dato, una evidencia y una conclusión.
    • Elaborar un informe técnico reproducible.

    3. Normas y alcance autorizado

    Esta actividad es exclusivamente de reconocimiento pasivo.

    Está permitido

    • Consultar fuentes públicas.
    • Utilizar Amass en modo -passive.
    • Utilizar Subfinder con sus fuentes OSINT.
    • Resolver registros DNS.
    • Consultar WHOIS y servicios públicos de información de IP.
    • Trabajar únicamente con el dominio indicado por el profesor.

    No está permitido

    • Escanear puertos con Nmap u otras herramientas.
    • Buscar vulnerabilidades o ejecutar exploits.
    • Realizar fuerza bruta de subdominios, directorios o credenciales.
    • Acceder a paneles, cuentas o zonas privadas.
    • Enviar tráfico masivo o intentar evadir límites.
    • Investigar dominios distintos de los autorizados.

    Encontrar un servicio visible no autoriza a entrar en él. Si descubres algo que parezca sensible, registra únicamente el nombre y comunícalo al profesor.


    4. Material necesario

    • Ubuntu, Debian, Kali Linux o una máquina virtual Linux.
    • Conexión a Internet.
    • Un dominio autorizado por el profesor.
    • Terminal y editor de texto.
    • Herramientas: amass, subfinder, dnsutils, whois, curl, jq y, opcionalmente, geoip-bin.

    El profesor proporcionará el objetivo:

    DOMINIO_AUTORIZADO=____________________________

    No sustituyas esta variable por el dominio de una empresa elegida al azar.


    5. Preparación del entorno

    Paso 1. Crear la estructura de trabajo

    mkdir -p operacion-atlas/{capturas,resultados,script}
    cd operacion-atlas

    Comprueba la estructura:

    find . -maxdepth 2 -type d

    Paso 2. Instalar las herramientas

    En una distribución basada en Ubuntu o Debian:

    sudo apt update
    sudo apt install amass dnsutils whois curl jq geoip-bin

    Si Subfinder no está disponible en los repositorios de tu distribución, sigue la opción de instalación explicada en la documentación del curso. Por ejemplo, si tienes Snap:

    sudo snap install subfinder

    Paso 3. Comprobar la instalación

    amass version
    subfinder -version
    host -V
    whois --version
    curl --version
    jq --version

    Evidencia 1: incluye una captura o salida de terminal que demuestre que las herramientas están disponibles. Si alguna no se puede instalar, explica el problema y continúa con las que funcionen.


    6. Fase 1: reconocimiento inicial

    Antes de ejecutar herramientas, completa una pequeña ficha:

    CampoRespuesta
    Dominio autorizado
    Fecha y hora de inicio
    Sistema operativo
    Hipótesis inicial
    ¿Qué información esperas encontrar?

    Formula al menos dos hipótesis. Por ejemplo:

    • El dominio puede utilizar varios subdominios para separar servicios.
    • Parte de la infraestructura puede estar alojada en un proveedor cloud.

    No importa si después resultan incorrectas: deberán contrastarse con evidencias.


    7. Fase 2: enumeración pasiva con Amass

    Paso 1. Ejecutar Amass en modo pasivo

    Sustituye dominio-autorizado.example por el objetivo indicado por el profesor:

    amass enum -passive -d dominio-autorizado.example \
      -o resultados/amass.txt

    El parámetro -passive es obligatorio en este reto.

    Paso 2. Revisar los resultados

    cat resultados/amass.txt

    Cuenta los resultados:

    wc -l resultados/amass.txt

    Ordénalos y elimina duplicados:

    sort -u resultados/amass.txt -o resultados/amass_limpio.txt

    Paso 3. Interpretar

    Responde:

    1. ¿Cuántos subdominios distintos encontró Amass?
    2. ¿Qué nombres parecen corresponder a servicios web, correo, API, desarrollo o administración?
    3. ¿Un nombre como dev, test o staging demuestra que existe un entorno vulnerable? Justifica la respuesta.
    4. ¿Por qué el resultado de una fuente OSINT puede estar desactualizado?

    Evidencia 2: incluye el comando, el número de resultados y una selección razonada de hasta diez subdominios. No llenes el informe con capturas repetitivas.


    8. Fase 3: enumeración con Subfinder

    Paso 1. Ejecutar la segunda herramienta

    subfinder -d dominio-autorizado.example \
      -o resultados/subfinder.txt

    Paso 2. Limpiar la salida

    sort -u resultados/subfinder.txt -o resultados/subfinder_limpio.txt

    Paso 3. Comparar las herramientas

    Subdominios encontrados por ambas:

    comm -12 resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/coincidencias.txt

    Encontrados solamente por Amass:

    comm -23 resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/solo_amass.txt

    Encontrados solamente por Subfinder:

    comm -13 resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/solo_subfinder.txt

    Combina todos los resultados:

    sort -u resultados/amass_limpio.txt resultados/subfinder_limpio.txt \
      > resultados/subdominios_finales.txt

    Obtén los recuentos:

    wc -l resultados/amass_limpio.txt \
          resultados/subfinder_limpio.txt \
          resultados/coincidencias.txt \
          resultados/subdominios_finales.txt

    Completa la tabla:

    ResultadoCantidad
    Amass
    Subfinder
    Coincidencias
    Total único

    Preguntas:

    1. ¿Qué herramienta ha encontrado más resultados?
    2. ¿Por qué dos herramientas OSINT pueden devolver resultados diferentes?
    3. ¿Por qué una coincidencia entre ambas fuentes aumenta la confianza, pero no confirma por sí sola que el servicio esté activo?

    Evidencia 3: tabla comparativa y explicación de las diferencias.


    9. Fase 4: resolución DNS

    Ahora comprobarás qué nombres de la lista pueden resolverse actualmente.

    Paso 1. Probar manualmente un subdominio

    host subdominio.dominio-autorizado.example

    También puedes consultar registros concretos:

    dig +short A subdominio.dominio-autorizado.example
    dig +short AAAA subdominio.dominio-autorizado.example
    dig +short CNAME subdominio.dominio-autorizado.example

    Paso 2. Automatizar la resolución de la lista

    while IFS= read -r subdominio; do
      echo "### $subdominio"
      host "$subdominio"
    done < resultados/subdominios_finales.txt \
      | tee resultados/resolucion_dns.txt

    Paso 3. Crear una lista única de IPv4

    while IFS= read -r subdominio; do
      dig +short A "$subdominio"
    done < resultados/subdominios_finales.txt \
      | grep -E '^[0-9]+(\.[0-9]+){3}$' \
      | sort -u \
      > resultados/ips.txt

    Revisa el resultado:

    cat resultados/ips.txt
    wc -l resultados/ips.txt

    Paso 4. Analizar

    Responde:

    1. ¿Todos los nombres encontrados mediante OSINT resuelven actualmente?
    2. ¿Hay varios subdominios que apunten a la misma IP?
    3. ¿Has encontrado registros CNAME?
    4. ¿Qué puede significar que varios servicios compartan dirección IP?
    5. ¿Qué diferencia existe entre no resolver un nombre y demostrar que nunca existió?

    Evidencia 4: presenta una tabla con una muestra de entre cinco y diez resultados.

    SubdominioTipo de registroIP o destino¿Resuelve?Observación

    10. Fase 5: contexto de las direcciones IP

    Selecciona un máximo de cinco IP públicas distintas. No es necesario consultar todas si la lista es muy grande.

    Paso 1. Consulta WHOIS

    whois DIRECCION_IP

    Busca datos como:

    • Organización o propietario del rango.
    • ASN, si aparece.
    • País de registro.
    • Rango o bloque de red.
    • Contactos de abuso, sin utilizarlos ni recopilar datos innecesarios.

    El país registrado en WHOIS no tiene por qué coincidir con la ubicación física exacta del servidor.

    Paso 2. Consulta GeoIP local

    geoiplookup DIRECCION_IP

    Paso 3. Consulta una API desde terminal

    curl -s "https://ipinfo.io/DIRECCION_IP/json" | jq

    Extrae solamente algunos campos:

    curl -s "https://ipinfo.io/DIRECCION_IP/json" \
      | jq '{ip, city, region, country, org, loc}'

    Respeta los límites del servicio: una consulta por cada IP seleccionada es suficiente.

    Paso 4. Correlacionar

    Completa la tabla:

    IPSubdominios asociadosOrganización/ASNPaís aproximadoPosible proveedorConfianza
    Alta/Media/Baja

    Responde:

    1. ¿Parece infraestructura propia, alojamiento compartido, CDN o proveedor cloud?
    2. ¿Coinciden WHOIS, GeoIP y la API?
    3. ¿Qué campos son hechos observados y cuáles son inferencias?
    4. ¿Por qué no debemos presentar una geolocalización de IP como una ubicación exacta?

    Evidencia 5: tabla completada y una conclusión prudente sobre la infraestructura.


    11. Fase 6: construir el script atlas.sh

    Debes crear un script que automatice el proceso básico.

    Requisitos mínimos

    El script deberá:

    1. Recibir un dominio como argumento.
    2. Comprobar que se ha indicado dicho argumento.
    3. Crear un directorio de resultados.
    4. Ejecutar Amass en modo pasivo.
    5. Ejecutar Subfinder.
    6. Combinar y eliminar duplicados.
    7. Resolver las direcciones IPv4.
    8. Guardar los resultados en archivos.
    9. Mostrar un resumen final.

    Plantilla orientativa

    Guárdala como script/atlas.sh y completa las partes marcadas:

    #!/usr/bin/env bash
    
    set -u
    
    if [ "$#" -ne 1 ]; then
      echo "Uso: $0 dominio-autorizado.example"
      exit 1
    fi
    
    DOMINIO="$1"
    FECHA="$(date +%Y%m%d_%H%M%S)"
    SALIDA="resultados_${DOMINIO}_${FECHA}"
    
    mkdir -p "$SALIDA"
    
    echo "[+] Iniciando reconocimiento pasivo de: $DOMINIO"
    
    # 1. Comprobar que las herramientas necesarias existen.
    # PISTA: command -v nombre_herramienta
    
    # 2. Ejecutar Amass exclusivamente en modo pasivo.
    
    # 3. Ejecutar Subfinder.
    
    # 4. Ordenar, combinar y eliminar duplicados.
    
    # 5. Resolver las direcciones IPv4 con dig.
    
    # 6. Mostrar el número de subdominios e IP únicas.
    
    echo "[+] Proceso finalizado. Resultados guardados en: $SALIDA"

    Da permiso de ejecución:

    chmod +x script/atlas.sh

    Ejecútalo únicamente con el dominio autorizado:

    ./script/atlas.sh dominio-autorizado.example

    Validaciones que debe incorporar

    Como mínimo, comprueba la presencia de cada herramienta:

    if ! command -v amass >/dev/null 2>&1; then
      echo "Error: Amass no está instalado."
      exit 1
    fi

    Repite o adapta la validación para las demás herramientas.

    Pruebas obligatorias

    Documenta qué ocurre cuando:

    • Se ejecuta sin argumentos.
    • Se ejecuta con el dominio autorizado.
    • Falta una herramienta necesaria.
    • Una de las herramientas no devuelve resultados.

    Evidencia 6: código completo del script, capturas o salidas de las pruebas y explicación de su funcionamiento.


    12. Fase 7: análisis final

    Redacta una conclusión que responda a estas preguntas:

    1. ¿Cuál es la superficie externa observada?
    2. ¿Cuántos subdominios únicos se han identificado?
    3. ¿Cuántos resolvían en el momento del análisis?
    4. ¿Qué proveedores o redes parecen alojarlos?
    5. ¿Existen indicios de servicios de desarrollo, pruebas, API o correo?
    6. ¿Qué resultados tienen una confianza alta, media o baja?
    7. ¿Qué limitaciones ha tenido la investigación?
    8. ¿Se confirmaron las hipótesis iniciales?
    9. ¿Qué recomendarías revisar al responsable del dominio?

    Las recomendaciones deben ser defensivas. Por ejemplo:

    • Mantener un inventario de subdominios.
    • Eliminar registros DNS abandonados.
    • Revisar nombres que revelen información innecesaria.
    • Comprobar que los entornos de prueba no estén publicados accidentalmente.
    • Repetir periódicamente el inventario pasivo.

    No afirmes que existe una vulnerabilidad si no dispones de evidencia suficiente.


    13. Entrega

    Entrega un archivo ZIP con esta estructura:

    operacion-atlas/
    ├── README.md
    ├── capturas/
    │   ├── 01_herramientas.png
    │   ├── 02_amass.png
    │   ├── 03_subfinder.png
    │   └── ...
    ├── resultados/
    │   ├── amass.txt
    │   ├── subfinder.txt
    │   ├── coincidencias.txt
    │   ├── subdominios_finales.txt
    │   ├── resolucion_dns.txt
    │   └── ips.txt
    └── script/
        └── atlas.sh

    El archivo README.md será el informe principal y deberá contener:

    1. Portada e identificación del alumno o equipo.
    2. Objetivo y alcance autorizado.
    3. Entorno y herramientas.
    4. Hipótesis iniciales.
    5. Procedimiento reproducible.
    6. Evidencias seleccionadas.
    7. Tablas de resultados.
    8. Explicación del script.
    9. Conclusiones y recomendaciones.
    10. Limitaciones y fuentes consultadas.

    No se valorará mejor un informe por tener más capturas. Se valorará que cada evidencia sea legible, necesaria y esté interpretada.


    14. Rúbrica de evaluación

    CriterioPuntuación
    Preparación, alcance ético y organización1 punto
    Enumeración pasiva con Amass y Subfinder2 puntos
    Limpieza, comparación y combinación de resultados1,5 puntos
    Resolución DNS y análisis de IP1,5 puntos
    Script Bash, validaciones y pruebas2 puntos
    Interpretación, correlación y conclusiones1,5 puntos
    Calidad del README y evidencias0,5 puntos
    Total10 puntos

    Penalizaciones importantes

    • Uso de técnicas activas no autorizadas: la práctica podrá considerarse no superada.
    • Investigación de dominios fuera del alcance: la práctica podrá considerarse no superada.
    • Script que no se explica o no se prueba: no se considerará completamente válido.
    • Capturas sin interpretación: tendrán poco valor como evidencia.
    • Resultados o conclusiones inventados: penalización grave.

    15. Nivel avanzado opcional: inteligencia reproducible

    Quienes terminen antes pueden incorporar estas mejoras:

    Mejora A. Archivo CSV

    Genera un archivo con el formato:

    subdominio,ip
    www.dominio.example,203.0.113.10
    api.dominio.example,203.0.113.20

    Mejora B. Parámetros adicionales

    Permite utilizar:

    ./script/atlas.sh -d dominio-autorizado.example -o informe

    Mejora C. Registro de ejecución

    Guarda fecha, herramienta, versión y comando ejecutado en un archivo log.txt.

    Mejora D. Manejo de errores

    Haz que el script continúe de forma controlada si Amass o Subfinder falla, indicando qué fuente no estuvo disponible.

    Mejora E. Comparación temporal

    Ejecuta el análisis en dos momentos autorizados distintos y compara las listas:

    comm -13 resultado_anterior.txt resultado_actual.txt

    Explica qué nombres son nuevos, cuáles han desaparecido y por qué eso no basta para asegurar que se haya producido un cambio real en la infraestructura.


    16. Pregunta de cierre

    Si todas las herramientas utilizadas consultan fuentes públicas, ¿por qué sigue siendo necesario definir un alcance, aplicar límites y tratar los resultados con responsabilidad?

  • Auditoría pasiva con Google Dorks

    Auditoría pasiva con Google Dorks

    Situación

    La empresa ficticia Nébula Systems está preparando una revisión de seguridad. La dirección sospecha que algunos documentos, formularios, directorios o páginas antiguas pueden estar apareciendo en buscadores sin que el equipo técnico sea consciente de ello.

    Vuestro equipo ha sido contratado para realizar una auditoría OSINT pasiva. No debéis atacar servidores, probar contraseñas ni explotar vulnerabilidades. Vuestra misión consiste en utilizar operadores avanzados de búsqueda para descubrir qué información pública puede localizar un usuario externo y proponer cómo reducir esa exposición.

    El trabajo se basa en la documentación Google Hacking de La Aventura de Aprender:


    Objetivos de aprendizaje

    Al finalizar el reto deberéis ser capaces de:

    • Explicar qué son Google Hacking y Google Dorks.
    • Utilizar operadores avanzados de búsqueda de forma combinada.
    • Diferenciar un hallazgo real, un falso positivo y un resultado irrelevante.
    • Evaluar el riesgo de la información indexada.
    • Registrar evidencias sin recopilar datos personales ni información sensible.
    • Proponer medidas de mitigación adecuadas.
    • Elaborar un informe técnico reproducible en Markdown.

    Normas de seguridad y uso ético

    Este reto solo puede realizarse sobre uno de estos objetivos:

    1. Un dominio de laboratorio proporcionado por el profesor.
    2. Un dominio propio del centro o del alumno para el que exista autorización.
    3. Dominios de demostración indicados expresamente por el profesor.

    Está permitido

    • Realizar búsquedas en Google, Bing o DuckDuckGo.
    • Analizar únicamente la información que aparece en los resultados del buscador.
    • Visitar páginas públicas ordinarias cuando el profesor lo haya autorizado.
    • Registrar URL, título, descripción y tipo de información encontrada.
    • Consultar GHDB para aprender a construir consultas.

    Está prohibido

    • Buscar deliberadamente contraseñas, claves privadas, tokens, datos médicos o datos personales reales.
    • Descargar bases de datos, copias de seguridad, archivos de configuración o documentos sensibles.
    • Acceder a paneles de administración o intentar iniciar sesión.
    • Realizar escaneos, fuerza bruta, explotación de vulnerabilidades o evasión de controles.
    • Automatizar búsquedas masivas.
    • Compartir públicamente una exposición real.

    Si aparece accidentalmente información sensible, no la abráis, no la descarguéis y no la copiéis. Detened la investigación, anotad de forma genérica que se ha localizado un posible hallazgo y avisad al profesor.


    Organización

    • Modalidad: individual o parejas.
    • Duración recomendada: 2 sesiones de 90 minutos.
    • Producto final: un repositorio o archivo ZIP con un README.md y una carpeta img.
    • Nombre recomendado: reto-google-dorks-apellido1-apellido2.

    Desarrollo paso a paso

    Fase 0. Preparación del entorno

    1. Cread una carpeta con la siguiente estructura:
    reto-google-dorks/
    ├── README.md
    └── img/
    1. En el README.md, añadid:
    • Título del reto.
    • Nombre de los integrantes.
    • Fecha.
    • Dominio autorizado asignado.
    • Buscador utilizado.
    • Declaración ética: “La investigación se ha realizado mediante técnicas pasivas y sobre un objetivo autorizado”.
    1. Leed la documentación de referencia antes de realizar búsquedas.

    Evidencia requerida: captura de la estructura del proyecto o bloque de código que la represente.


    Fase 1. Comprender los operadores

    Explicad con vuestras propias palabras para qué sirven los siguientes operadores:

    Operador¿Qué debéis explicar?
    site:Cómo limita la búsqueda a un dominio
    filetype:Cómo filtra por tipo de documento
    inurl:Cómo busca términos dentro de la URL
    intitle:Cómo busca términos en el título
    intext:Cómo busca texto dentro de una página
    "frase exacta"Qué cambia al utilizar comillas
    -terminoCómo se excluyen resultados
    ORCómo se ofrecen alternativas

    Después, cread un ejemplo seguro y genérico de cada uno empleando example.com o el dominio autorizado.

    No copiéis únicamente las definiciones de la documentación. Debéis explicar qué utilidad tendría cada operador durante una auditoría.

    Evidencia requerida: tabla de operadores, explicación y ejemplo.


    Fase 2. Reconocimiento inicial del dominio

    Sustituid DOMINIO-AUTORIZADO por el objetivo asignado.

    1. Ejecutad una búsqueda general:
    site:DOMINIO-AUTORIZADO
    1. Observad las primeras páginas de resultados y anotad:
    • Número aproximado de resultados indicado por el buscador.
    • Tipos de páginas que aparecen.
    • Secciones o subdominios visibles.
    • Resultados antiguos, duplicados o inesperados.
    1. Repetid la consulta añadiendo al menos dos palabras relevantes para la organización, por ejemplo:
    site:DOMINIO-AUTORIZADO contacto
    site:DOMINIO-AUTORIZADO formación
    1. Comparad los resultados y explicad qué información básica podría obtener un tercero.

    El número de resultados del buscador es aproximado y puede variar. No debe tratarse como una medición exacta.

    Evidencia requerida: consultas empleadas, fecha, resumen de resultados y una captura sin datos personales.


    Fase 3. Localización de documentos públicos

    Buscad documentos que la organización publique de forma legítima. Realizad al menos cuatro consultas usando tipos diferentes:

    site:DOMINIO-AUTORIZADO filetype:pdf
    site:DOMINIO-AUTORIZADO filetype:docx
    site:DOMINIO-AUTORIZADO filetype:xlsx
    site:DOMINIO-AUTORIZADO filetype:pptx

    Si una extensión no ofrece resultados, registrad igualmente la consulta. Un resultado negativo también es una evidencia válida.

    Para cada consulta, indicad:

    • Qué pretendíais encontrar.
    • Qué habéis encontrado.
    • Si el resultado parece intencionadamente público.
    • Qué información revela el título o el fragmento mostrado por Google.
    • Riesgo inicial: informativo, bajo, medio o alto.

    No descarguéis documentos que parezcan internos, confidenciales o que contengan datos personales.

    Evidencia requerida: tabla comparativa de al menos cuatro búsquedas.


    Fase 4. Identificación de rutas y servicios visibles

    Realizad búsquedas orientadas a reconocer la estructura pública del sitio:

    site:DOMINIO-AUTORIZADO inurl:login
    site:DOMINIO-AUTORIZADO inurl:admin
    site:DOMINIO-AUTORIZADO inurl:portal
    site:DOMINIO-AUTORIZADO inurl:uploads
    site:DOMINIO-AUTORIZADO inurl:documentos

    Podéis adaptar las palabras al contexto del objetivo. No accedáis a paneles ni intentéis autenticaros.

    Responded:

    1. ¿La existencia pública de una página de inicio de sesión es por sí sola una vulnerabilidad?
    2. ¿Qué información puede revelar la estructura de una URL?
    3. ¿Qué resultados son normales y cuáles deberían revisarse?
    4. ¿Habéis detectado falsos positivos?

    Evidencia requerida: mínimo tres consultas comentadas y clasificación de sus resultados.


    Fase 5. Consultas combinadas

    Ahora debéis construir búsquedas más precisas combinando operadores. Cread y probad al menos cinco consultas propias.

    Ejemplos seguros:

    site:DOMINIO-AUTORIZADO filetype:pdf "manual"
    site:DOMINIO-AUTORIZADO (filetype:pdf OR filetype:docx) "curso"
    site:DOMINIO-AUTORIZADO inurl:uploads filetype:pdf
    site:DOMINIO-AUTORIZADO intitle:"contacto"
    site:DOMINIO-AUTORIZADO filetype:pdf -inurl:blog

    Cada consulta deberá incluir:

    • Hipótesis: qué creéis que puede localizar.
    • Dork utilizado.
    • Resultado obtenido.
    • Interpretación.
    • Modificación realizada para mejorar la precisión.

    Al menos una consulta debe usar OR, otra debe excluir un término con - y otra debe combinar tres operadores.

    Evidencia requerida: cinco fichas de consulta completas.


    Fase 6. Investigación en GHDB

    Consultad la Google Hacking Database enlazada en la documentación.

    1. Elegid dos categorías relacionadas con exposición de información.
    2. Seleccionad un ejemplo de consulta de cada categoría.
    3. Explicad qué intenta localizar, sin ejecutarlo sobre organizaciones reales.
    4. Transformadlo en una versión segura para el dominio de laboratorio.
    5. Indicad qué riesgo representaría un resultado positivo.

    No se valorará que el dork sea espectacular, sino que comprendáis su funcionamiento y sepáis adaptarlo de manera responsable.

    Evidencia requerida: dos análisis de dorks de GHDB, con referencia a su categoría y versión adaptada.


    Fase 7. Comparación entre buscadores

    Elegid dos consultas anteriores y repetidlas en otro buscador, como Bing o DuckDuckGo.

    Comparad:

    • Cantidad y relevancia de resultados.
    • Documentos que aparecen en uno y no en otro.
    • Diferencias en títulos y fragmentos.
    • Posibles causas de las diferencias.

    No es necesario que todos los buscadores admitan exactamente los mismos operadores. Si uno no funciona, documentadlo.

    Evidencia requerida: tabla comparativa de dos consultas en dos buscadores.


    Fase 8. Registro y clasificación de hallazgos

    Reunid los resultados relevantes en una tabla como esta:

    IDConsultaHallazgo resumidoEvidenciaProbabilidadImpactoRiesgo¿Falso positivo?
    H-01site:... filetype:pdfDocumento público antiguoURL y capturaMediaBajoBajoNo

    Utilizad esta escala:

    • Informativo: no existe un problema, pero el resultado ayuda a conocer la huella digital.
    • Bajo: información pública poco sensible o desactualizada.
    • Medio: información no prevista que facilita reconocimiento o ingeniería social.
    • Alto: posible exposición de información interna o sensible. No debe abrirse; se comunica al profesor.

    Para cada hallazgo relevante, explicad por qué le asignáis esa valoración. El nivel de riesgo no depende de que el resultado “parezca interesante”, sino de su impacto y probabilidad.

    Evidencia requerida: inventario de hallazgos. Puede haber hallazgos informativos o resultados negativos.


    Fase 9. Plan de mitigación

    Proponed al menos una medida concreta para cada hallazgo que necesite corrección. Podéis considerar:

    • Retirar documentos que ya no deban ser públicos.
    • Mover copias de seguridad fuera del directorio web.
    • Desactivar el listado de directorios.
    • Revisar permisos y reglas del servidor.
    • Proteger áreas privadas mediante autenticación y autorización.
    • Evitar publicar información sensible en nombres de archivo, títulos o metadatos.
    • Solicitar la retirada de resultados obsoletos del buscador.
    • Utilizar noindex cuando proceda.
    • Revisar robots.txt, entendiendo que no es un mecanismo de seguridad.

    Para cada medida indicad:

    • Hallazgo al que responde.
    • Acción propuesta.
    • Responsable recomendado.
    • Prioridad.
    • Cómo comprobaríais posteriormente que la corrección funciona.

    Evidencia requerida: plan de mitigación priorizado.


    Fase 10. Conclusiones

    Responded razonadamente:

    1. ¿Qué diferencia existe entre una búsqueda normal y un Google Dork?
    2. ¿Por qué una página indexada no es automáticamente una vulnerabilidad?
    3. ¿Cuál ha sido la combinación de operadores más útil?
    4. ¿Qué limitaciones tiene este tipo de auditoría?
    5. ¿Qué riesgo puede tener publicar documentos aparentemente inofensivos?
    6. ¿Qué debe hacer un auditor si encuentra información sensible de forma accidental?
    7. ¿Qué cambiaríais en la exposición pública del dominio analizado?

    Misión extra

    Quienes terminen el reto principal pueden realizar esta ampliación:

    1. Diseñad una matriz con tres objetivos: documentos, rutas y contenido textual.
    2. Cread tres consultas diferentes para cada objetivo, sin ejecutar búsquedas agresivas.
    3. Comparad los resultados actuales con una versión histórica pública del sitio mediante Wayback Machine, si el profesor lo autoriza.
    4. Seleccionad un documento público e indicad qué metadatos sería razonable revisar en un laboratorio, sin descargar material sensible.
    5. Diseñad una consulta periódica que la propia organización podría usar para vigilar su exposición.
    6. Proponed un procedimiento responsable de notificación de hallazgos.

    La ampliación debe centrarse en la metodología y la defensa. No se permite utilizar herramientas automáticas de escaneo.


    Estructura obligatoria del README.md

    # Operación Huella Digital
    
    ## 1. Datos del equipo
    ## 2. Objetivo y autorización
    ## 3. Declaración ética
    ## 4. Operadores estudiados
    ## 5. Reconocimiento inicial
    ## 6. Búsqueda de documentos
    ## 7. Rutas y servicios visibles
    ## 8. Consultas combinadas
    ## 9. Investigación en GHDB
    ## 10. Comparación de buscadores
    ## 11. Inventario de hallazgos
    ## 12. Plan de mitigación
    ## 13. Conclusiones
    ## 14. Bibliografía y recursos

    Las capturas deberán guardarse en img/ y enlazarse mediante rutas relativas:

    ![Resultado de una consulta autorizada](img/consulta-01.png)

    Antes de incluir una captura, ocultad nombres, correos, identificadores, cookies, cuentas abiertas y cualquier dato personal.


    Entrega

    La entrega debe contener:

    • README.md completo y bien estructurado.
    • Carpeta img con las evidencias necesarias.
    • Entre 10 y 15 consultas propias documentadas.
    • Al menos cinco consultas combinadas.
    • Comparación de dos buscadores.
    • Inventario de hallazgos.
    • Plan de mitigación.
    • Conclusiones personales.

    Aunque inicialmente se entregue como ZIP, el proyecto deberá estar preparado para subirse posteriormente a un repositorio Git.

    No incluyáis archivos obtenidos durante la investigación. Solo se entregarán el informe y capturas saneadas.


    Rúbrica de evaluación

    CriterioPeso
    Uso correcto y variado de operadores20 %
    Metodología paso a paso y reproducibilidad15 %
    Interpretación de resultados y falsos positivos15 %
    Clasificación razonada de riesgos15 %
    Medidas de mitigación15 %
    Calidad del README.md y de las evidencias10 %
    Ética, privacidad y cumplimiento de las normas10 %

    Penalizaciones

    • Ejecutar pruebas fuera de los objetivos autorizados: actividad no superada.
    • Incluir datos personales o información sensible en la entrega: actividad no superada hasta corregirla.
    • Presentar consultas sin explicar su finalidad y sus resultados: no se consideran realizadas.
    • Copiar definiciones sin interpretación propia: reducción de la puntuación correspondiente.

    Lista de comprobación final

    • He trabajado únicamente sobre un objetivo autorizado.
    • No he intentado iniciar sesión ni explotar ningún sistema.
    • He documentado las consultas aunque no ofrecieran resultados.
    • He diferenciado hallazgos, falsos positivos y resultados irrelevantes.
    • Las capturas no contienen datos personales.
    • No he descargado ni adjuntado información sensible.
    • Cada riesgo incluye una medida de mitigación.
    • El README.md puede entenderse sin explicaciones adicionales.
    • He citado la documentación utilizada.

    Resultado esperado

    El objetivo no es encontrar “secretos”, sino demostrar que sabéis formular preguntas precisas a un buscador, interpretar responsablemente las respuestas y convertir la información pública en recomendaciones defensivas útiles.

    Dominios recomendados para búsquedas inocuas

    En estos dominios limitaría la práctica a operadores como site:, filetype:, intitle:, inurl: y frases entre comillas, buscando exclusivamente información pública.

    DominioTemáticaEjemplos seguros
    boe.esLegislación españolasite:boe.es filetype:pdf ciberseguridad
    ine.esEstadísticas públicassite:ine.es filetype:xlsx población
    datos.gob.esDatos abiertossite:datos.gob.es filetype:csv transporte
    administracion.gob.esAdministración públicasite:administracion.gob.es filetype:pdf empleo
    europa.euUnión Europeasite:europa.eu filetype:pdf cybersecurity
    data.europa.euDatos abiertos europeossite:data.europa.eu \"open data\"
    who.intSalud pública internacionalsite:who.int filetype:pdf cybersecurity
    un.orgNaciones Unidassite:un.org filetype:pdf \"artificial intelligence\"
    nasa.govCiencia y espaciosite:nasa.gov filetype:pdf mars
    noaa.govMeteorología y océanossite:noaa.gov filetype:pdf climate
    mit.eduUniversidad e investigaciónsite:mit.edu filetype:pdf \"computer security\"
    stanford.eduInvestigación académicasite:stanford.edu filetype:pptx cybersecurity
    docs.python.orgDocumentación técnicasite:docs.python.org intitle:\"Python\" tutorial
    developer.mozilla.orgDesarrollo website:developer.mozilla.org \"HTTP authentication\"
    wikipedia.orgContenido enciclopédicosite:wikipedia.org intitle:OSINT
    archive.orgArchivo históricosite:archive.org filetype:pdf networking
  • OSINT – Investigación digital a partir de una fotografía

    OSINT – Investigación digital a partir de una fotografía

    Investigación digital a partir de una fotografía

    1. Introducción

    Una fotografía puede contener mucha más información de la que se aprecia a simple vista. Además de la propia imagen, el archivo puede guardar metadatos técnicos, fechas, coordenadas, información del dispositivo utilizado y otros datos.

    En esta práctica asumirás el papel de un analista OSINT (Open Source Intelligence). Tu misión será investigar una fotografía y obtener toda la información posible empleando únicamente fuentes abiertas, herramientas gratuitas y técnicas legales.

    No todas las fotografías contienen las mismas pistas. Por tanto, no es obligatorio completar con éxito todos los apartados. También se valorará que expliques correctamente:

    • Qué técnica has utilizado.
    • Qué resultado has obtenido.
    • Qué limitaciones has encontrado.
    • Qué información no has podido verificar.
    • Por qué consideras fiable o no una conclusión.

    2. Objetivos

    Al finalizar la práctica deberás ser capaz de:

    • Examinar técnicamente un archivo de imagen.
    • Extraer e interpretar sus metadatos.
    • Realizar búsquedas inversas de imágenes.
    • Analizar visualmente lugares, objetos, textos y personas sin identificarlas de forma invasiva.
    • Aplicar técnicas básicas de geolocalización.
    • Buscar información relacionada en fuentes abiertas.
    • Contrastar información utilizando varias fuentes.
    • Diferenciar entre evidencia, indicio, hipótesis y conclusión.
    • Documentar de forma ordenada una investigación OSINT.
    • Comprender los riesgos de privacidad asociados a las fotografías.

    3. Normas de la investigación

    La práctica se realizará únicamente con:

    • Fotografías proporcionadas por el profesor.
    • Fotografías propias.
    • Imágenes publicadas con una licencia adecuada.
    • Imágenes de lugares públicos o utilizadas expresamente con fines educativos.

    No está permitido:

    • Investigar a compañeros, profesores o particulares sin su consentimiento.
    • Intentar acceder a cuentas privadas.
    • Contactar con personas que aparezcan en la fotografía.
    • Publicar datos personales obtenidos durante la investigación.
    • Utilizar reconocimiento facial para identificar personas reales.
    • Acosar, seguir o localizar el domicilio de una persona.
    • Modificar o destruir el archivo original.
    • Presentar como segura una información que solamente es una suposición.

    4. Preparación del archivo

    Antes de empezar, crea una carpeta con la siguiente estructura:

    investigacion-osint/
    ├── imagen-original/
    ├── copias-trabajo/
    ├── capturas/
    ├── evidencias/
    └── README.md

    Guarda la fotografía original sin modificar dentro de imagen-original.

    Realiza todas las pruebas sobre una copia situada en copias-trabajo.

    Registro inicial

    Anota:

    • Nombre del archivo.
    • Formato.
    • Tamaño en bytes.
    • Dimensiones en píxeles.
    • Fecha y hora en la que recibiste el archivo.
    • Procedencia conocida de la fotografía.
    • Herramienta utilizada para obtener cada dato.

    Integridad del archivo

    Calcula al menos el hash SHA-256 de la fotografía.

    Ejemplo con Linux:

    sha256sum fotografia.jpg

    Ejemplo con PowerShell:

    Get-FileHash fotografia.jpg -Algorithm SHA256

    Explica para qué sirve un hash y por qué resulta útil conservarlo durante una investigación.


    5. Líneas posibles de investigación

    Deberás realizar todas las fases básicas y elegir varias investigaciones adicionales según las características de la fotografía.

    Fase 1. Inspección visual inicial

    Observa la imagen antes de utilizar buscadores o herramientas automáticas.

    Busca y registra elementos como:

    • Carteles.
    • Matrículas, que deberán ocultarse en la entrega.
    • Nombres de calles.
    • Nombres de comercios.
    • Logotipos.
    • Idiomas.
    • Señales de tráfico.
    • Banderas.
    • Edificios o monumentos.
    • Medios de transporte.
    • Uniformes.
    • Vegetación.
    • Tipo de carretera.
    • Arquitectura.
    • Mobiliario urbano.
    • Clima.
    • Relieve del terreno.
    • Posición del sol.
    • Sombras.
    • Cualquier elemento poco habitual.

    Crea una primera lista de hipótesis sin realizar todavía búsquedas.

    Ejemplo:

    ObservaciónPosible significadoGrado de confianza
    Señal triangular con borde rojoProbablemente EuropaMedio
    Texto aparentemente en portuguésPortugal o BrasilBajo
    Tranvía amarilloPodría ser LisboaBajo

    Las primeras hipótesis pueden ser incorrectas. Esto no se penalizará si posteriormente se contrastan.


    Fase 2. Análisis de metadatos

    Comprueba si la fotografía contiene metadatos EXIF, IPTC o XMP.

    Puedes utilizar herramientas como:

    • ExifTool.
    • Metadata2Go.
    • Jeffrey’s Image Metadata Viewer.
    • Exif.tools.
    • Propiedades del archivo del sistema operativo.

    Busca, si están disponibles, los siguientes campos:

    • Fabricante del dispositivo.
    • Modelo de cámara o teléfono.
    • Fecha y hora de captura.
    • Fecha de modificación.
    • Software utilizado.
    • Orientación.
    • Resolución.
    • Distancia focal.
    • Apertura.
    • Tiempo de exposición.
    • Sensibilidad ISO.
    • Uso del flash.
    • Coordenadas GPS.
    • Altitud.
    • Miniatura incrustada.
    • Autor o propietario.
    • Comentarios.
    • Copyright.

    Debes responder:

    1. ¿Qué metadatos conserva la fotografía?
    2. ¿Cuáles pueden ser útiles para la investigación?
    3. ¿Podrían haber sido modificados?
    4. ¿Existe alguna contradicción entre los metadatos y la imagen?
    5. ¿La fecha corresponde a la captura o a una modificación posterior?
    6. ¿Qué información privada podría revelar el archivo?

    Si aparecen coordenadas GPS, represéntalas en un mapa y compáralas con el contenido visible en la fotografía. No publiques coordenadas de domicilios particulares.


    Fase 3. Búsqueda inversa de imágenes

    Utiliza al menos dos servicios diferentes:

    • Google Lens.
    • Bing Visual Search.
    • TinEye.
    • Yandex Images.

    Compara los resultados obtenidos en cada buscador.

    Busca:

    • La misma fotografía.
    • Versiones recortadas.
    • Versiones con diferente resolución.
    • Publicaciones anteriores.
    • La posible fuente original.
    • Páginas donde se haya reutilizado.
    • Imágenes visualmente parecidas.
    • Posibles manipulaciones.

    Registra:

    BuscadorConsulta o imagen utilizadaResultado relevanteFecha del resultadoValoración

    Prueba también a realizar búsquedas con:

    • La imagen completa.
    • Un recorte de un edificio.
    • Un cartel o logotipo.
    • Un objeto singular.
    • El paisaje del fondo.
    • Una marca de agua.

    Indica cuál de los buscadores ha proporcionado mejores resultados y por qué.


    Fase 4. Extracción y análisis de texto

    Busca cualquier texto presente en la imagen:

    • Carteles.
    • Escaparates.
    • Camisetas.
    • Vehículos.
    • Señales.
    • Billetes.
    • Pantallas.
    • Documentos.
    • Nombres comerciales.

    Puedes utilizar herramientas OCR como:

    • Google Lens.
    • Microsoft Lens.
    • OCR.Space.
    • Tesseract.
    • Herramientas de OCR integradas en móviles u ordenadores.

    Después:

    1. Copia el texto detectado.
    2. Corrige posibles errores del OCR.
    3. Identifica el idioma.
    4. Traduce el texto si es necesario.
    5. Busca frases exactas entre comillas.
    6. Investiga nombres, dominios, teléfonos o establecimientos.
    7. Comprueba si el texto permite relacionar la fotografía con una ubicación o acontecimiento.

    No debes llamar a teléfonos, escribir a direcciones ni contactar con las personas encontradas.


    Fase 5. Geolocalización

    Intenta determinar:

    • País.
    • Región o provincia.
    • Ciudad.
    • Zona aproximada.
    • Punto concreto, únicamente si se trata de un lugar público.

    Puedes utilizar las siguientes pistas:

    Infraestructura

    • Forma y color de las señales.
    • Marcas de la carretera.
    • Semáforos.
    • Farolas.
    • Contenedores.
    • Bolardos.
    • Aceras.
    • Cableado.
    • Postes eléctricos.
    • Paradas de transporte.
    • Matrículas, sin publicar números completos.

    Entorno natural

    • Vegetación.
    • Tipo de suelo.
    • Montañas.
    • Costa.
    • Clima.
    • Estación del año.
    • Fauna visible.

    Entorno urbano

    • Arquitectura.
    • Materiales de construcción.
    • Numeración de edificios.
    • Comercios.
    • Monumentos.
    • Transporte público.
    • Logotipos municipales.

    Herramientas de apoyo

    • Google Maps.
    • Google Street View.
    • Google Earth.
    • OpenStreetMap.
    • Mapillary.
    • Wikimapia.
    • GeoHints.
    • Overpass Turbo, como opción avanzada.

    La ubicación debe justificarse comparando elementos visibles. No será suficiente escribir: “Google Lens dice que es Madrid”.


    Fase 6. Análisis de objetos y elementos

    Selecciona varios objetos relevantes y trata de identificarlos:

    • Modelo aproximado de vehículo.
    • Marca de un producto.
    • Tipo de uniforme.
    • Modelo de teléfono u ordenador.
    • Obra de arte.
    • Monumento.
    • Planta o animal.
    • Máquina o herramienta.
    • Cartel publicitario.
    • Logotipo.

    Para cada elemento indica:

    • Qué crees que es.
    • Cómo lo has buscado.
    • Qué fuentes has consultado.
    • Qué características coinciden.
    • Qué características no coinciden.
    • Nivel de confianza de la identificación.

    Fase 7. Análisis temporal o cronolocalización

    Intenta estimar cuándo fue tomada la fotografía.

    Puedes investigar:

    • Fecha incluida en los metadatos.
    • Carteles de eventos.
    • Publicidad temporal.
    • Obras en edificios.
    • Estado de la vegetación.
    • Ropa de las personas.
    • Meteorología.
    • Decoración navideña o festividades.
    • Modelos de vehículos.
    • Versiones de productos.
    • Posición del sol y dirección de las sombras.
    • Imágenes históricas de Street View.
    • Noticias o publicaciones relacionadas.

    Clasifica el resultado como:

    • Fecha exacta confirmada.
    • Intervalo temporal probable.
    • Estación del año estimada.
    • Fecha desconocida.

    Explica siempre qué evidencias apoyan la estimación.


    Fase 8. Análisis meteorológico

    Si has deducido una posible fecha y lugar, comprueba si el tiempo visible coincide con registros meteorológicos históricos.

    Observa:

    • Cielo despejado o cubierto.
    • Lluvia.
    • Nieve.
    • Suelo mojado.
    • Dirección aparente del viento.
    • Tipo de ropa.
    • Longitud de las sombras.
    • Estado de la vegetación.

    Este análisis no suele demostrar por sí solo una ubicación o fecha, pero puede servir para apoyar o descartar una hipótesis.


    Fase 9. Investigación del contexto

    Trata de averiguar por qué pudo tomarse la fotografía.

    Busca relaciones con:

    • Noticias.
    • Eventos.
    • Manifestaciones.
    • Conciertos.
    • Competiciones deportivas.
    • Ferias.
    • Inauguraciones.
    • Catástrofes naturales.
    • Obras públicas.
    • Publicaciones en páginas institucionales.
    • Bancos de imágenes.
    • Páginas turísticas.
    • Redes sociales públicas.

    No des por hecho que dos fotografías corresponden al mismo acontecimiento únicamente porque se parezcan.


    Fase 10. Comprobación de manipulación

    Analiza si la imagen presenta señales de edición o manipulación.

    Busca:

    • Sombras incoherentes.
    • Reflejos imposibles.
    • Diferencias de iluminación.
    • Bordes extraños.
    • Elementos repetidos.
    • Perspectiva incorrecta.
    • Texto deformado.
    • Zonas excesivamente borrosas.
    • Diferencias de compresión.
    • Metadatos de programas de edición.
    • Partes con distinta resolución.

    Puedes utilizar herramientas como:

    • Forensically.
    • FotoForensics.
    • ExifTool.
    • Ampliación y ajustes de contraste.
    • Búsqueda inversa de recortes.

    Las herramientas automáticas no proporcionan una prueba definitiva. Sus resultados deben interpretarse con prudencia.


    Fase 11. Esteganografía — ampliación avanzada

    Comprueba si la imagen podría contener información oculta.

    Posibles comprobaciones:

    • Archivos añadidos después del final de la imagen.
    • Texto incrustado.
    • Datos ocultos en los bits menos significativos.
    • Contenido comprimido dentro del archivo.
    • Información visible al separar canales de color.

    Herramientas posibles:

    • Binwalk.
    • Strings.
    • StegHide.
    • StegSeek.
    • Zsteg, para formatos compatibles.
    • Aperi’Solve.
    • CyberChef.

    Esta fase solamente debe realizarse sobre la imagen entregada para la práctica. No descargues ni ejecutes archivos desconocidos fuera del entorno controlado del laboratorio.


    6. Clasificación de los resultados

    Cada descubrimiento deberá etiquetarse de una de estas maneras:

    ClasificaciónSignificado
    Hecho confirmadoEstá demostrado mediante una evidencia fiable
    Muy probableExisten varias evidencias coincidentes
    PosibleHay algún indicio, pero no es suficiente
    HipótesisExplicación pendiente de comprobación
    DescartadoLas evidencias demuestran que no es correcto
    No determinadoNo se ha podido obtener información suficiente

    También asignarás un nivel de confianza:

    • Alto.
    • Medio.
    • Bajo.

    Ejemplo:

    La fotografía probablemente fue tomada en la Plaza Mayor de Salamanca. La arquitectura y el nombre visible de un comercio coinciden con Street View. Nivel de confianza: alto.


    7. Registro de evidencias

    Incluye una tabla general:

    IDDato investigadoHerramienta o fuenteResultadoClasificaciónConfianza
    E01Modelo del dispositivoExifTooliPhone 14Hecho confirmadoAlto
    E02CiudadStreet View y cartelValenciaMuy probableAlto
    E03FechaTipo de eventoMayo de 2024PosibleMedio

    Cada evidencia debe incluir:

    • Captura de pantalla.
    • Enlace a la fuente, cuando exista.
    • Fecha y hora de consulta.
    • Explicación del proceso.
    • Interpretación del resultado.

    Las capturas deben ocultar datos personales que no sean necesarios para la práctica.


    8. Informe final

    La entrega se realizará en un archivo README.md escrito en Markdown.

    Estructura obligatoria

    • Título de la investigación.
    • Nombre del alumno o equipo.
    • Curso.
    • Fecha.
    • Imagen reducida o censurada, si procede.

    2. Resumen ejecutivo

    Explicación breve de los principales descubrimientos.

    3. Descripción del archivo

    • Nombre.
    • Formato.
    • Tamaño.
    • Dimensiones.
    • Hash SHA-256.
    • Procedencia.

    4. Metodología

    Explicación de las fases realizadas y las herramientas empleadas.

    5. Análisis visual

    Observaciones iniciales e hipótesis.

    6. Análisis de metadatos

    Resultados obtenidos e interpretación.

    7. Búsqueda inversa

    Buscadores utilizados y resultados.

    8. Investigación del texto

    OCR, traducciones y búsquedas relacionadas.

    9. Geolocalización

    Proceso seguido para identificar el lugar.

    10. Análisis temporal

    Fecha o intervalo estimado.

    11. Otros análisis

    Objetos, contexto, meteorología, manipulación o esteganografía.

    12. Tabla de evidencias

    Listado completo de descubrimientos y nivel de confianza.

    13. Conclusiones

    Debes separar claramente:

    • Lo que has podido confirmar.
    • Lo que consideras probable.
    • Lo que no has podido determinar.
    • Las hipótesis descartadas.

    14. Reflexión sobre privacidad

    Responde:

    1. ¿Qué información sensible podría revelar una fotografía?
    2. ¿Qué datos eliminarías antes de publicarla?
    3. ¿Las redes sociales conservan siempre los metadatos?
    4. ¿Qué riesgos tiene publicar una imagen tomada en casa?
    5. ¿Cómo podría protegerse una persona antes de compartir fotografías?

    15. Fuentes consultadas

    Incluye todas las herramientas, páginas, mapas, artículos y documentos utilizados.


    9. Requisitos mínimos

    Para superar la práctica deberás realizar, como mínimo:

    • Inspección visual.
    • Cálculo del hash.
    • Análisis de metadatos.
    • Dos búsquedas inversas.
    • Extracción de texto, si existe.
    • Un intento razonado de geolocalización.
    • Análisis de al menos tres elementos visibles.
    • Tabla de evidencias.
    • Clasificación del nivel de confianza.
    • Reflexión sobre privacidad.
    • Documentación completa en Markdown.

    10. Opciones de ampliación

    Los alumnos que quieran profundizar podrán realizar una o varias de estas tareas:

    • Comparar los metadatos antes y después de enviar la fotografía por distintas plataformas.
    • Crear una copia sin metadatos y verificar su eliminación.
    • Analizar diferencias entre la imagen original y una versión publicada en una red social.
    • Utilizar Street View histórico.
    • Investigar la dirección de las sombras.
    • Comparar registros meteorológicos.
    • Buscar versiones anteriores de la fotografía.
    • Detectar posibles recortes o ediciones.
    • Utilizar herramientas de análisis forense.
    • Examinar si existe información oculta mediante esteganografía.
    • Elaborar una línea temporal de publicación.
    • Crear un mapa con los lugares candidatos.
    • Analizar cómo cambiarían los resultados si solamente se dispusiera de una captura de pantalla.

    11. Rúbrica orientativa

    ApartadoPorcentaje
    Organización, Markdown y presentación10 %
    Inspección visual y formulación de hipótesis10 %
    Análisis técnico y metadatos15 %
    Búsqueda inversa y localización de fuentes15 %
    OCR, objetos y pistas visuales10 %
    Geolocalización y análisis temporal15 %
    Evidencias, contraste y nivel de confianza15 %
    Conclusiones, privacidad y límites éticos10 %

    No se calificará únicamente la cantidad de información encontrada. Se valorará especialmente:

    • La calidad del razonamiento.
    • La capacidad de contrastar fuentes.
    • La documentación de los intentos fallidos.
    • La separación entre hechos e hipótesis.
    • El uso responsable de las herramientas.
    • La claridad de las conclusiones.

    12. Preguntas para la defensa

    El profesor podrá preguntar:

    • ¿Cuál ha sido la evidencia más importante?
    • ¿Qué dato parecía correcto inicialmente y luego descartaste?
    • ¿Qué herramienta te ha dado mejores resultados?
    • ¿Podrían estar manipulados los metadatos?
    • ¿Cómo has confirmado la ubicación?
    • ¿Qué grado de confianza asignas a tu conclusión?
    • ¿Qué otra explicación podría tener la evidencia?
    • ¿Qué dato no publicarías por motivos de privacidad?
    • ¿Podría otra persona reproducir tu investigación?
    • ¿Qué harías a continuación si dispusieras de más tiempo?

    13. Resultado esperado

    La investigación deberá finalizar con una conclusión prudente y verificable.

    No debes escribir:

    La foto fue tomada en Sevilla.

    Es preferible escribir:

    La fotografía fue tomada probablemente en Sevilla. El nombre del establecimiento visible coincide con un comercio situado en esa ciudad y la fachada puede verificarse en Street View. No se dispone de coordenadas GPS, por lo que la ubicación se clasifica como muy probable, con un nivel de confianza alto.

    En OSINT, reconocer que no existen pruebas suficientes también es un resultado válido.


    RETOS

    1. Plaza del Faro

    naliza el archivo reto_osint_plaza_del_faro.jpg y obtén toda la información posible sin consultar la solución del profesor.

    Debes estudiar:

    • Elementos visibles y posibles pistas engañosas.
    • Textos mediante OCR.
    • Lugar y momento aproximados.
    • Coherencia de luces y sombras.
    • Metadatos técnicos, EXIF, IPTC o XMP.
    • Posible contenido añadido u oculto en el archivo.
    • Diferencia entre hechos, indicios e hipótesis.

    2. Estación ferroviaria ficticia de montaña.

    Analiza reto_osint_estacion_valle_nevado.jpg sin consultar la soluciçon del profesor.

    Investiga los elementos visibles, los textos mediante OCR, la estación del año, la meteorología, la hora aproximada, los metadatos y cualquier contenido añadido al archivo.

    Debes diferenciar entre:

    • Evidencias confirmadas.
    • Indicios razonables.
    • Hipótesis pendientes.
    • Pistas engañosas.

    3. Bilbao

    Analiza el archivo reto_osint_avanzado_bilbao.png y reconstruye toda la cadena de evidencias.

    Objetivos

    • Geolocalizar la escena utilizando varias evidencias independientes.
    • Estimar fecha, hora, estación del año y condiciones meteorológicas.
    • Extraer textos mediante OCR y distinguir pistas válidas de señuelos.
    • Examinar la estructura interna del PNG y sus bloques de metadatos.
    • Detectar información codificada y explicar cómo se ha decodificado.
    • Comprobar si los canales de color contienen información oculta.
    • Detectar datos anexados después del final lógico de la imagen.
    • Construir y justificar la contraseña necesaria para recuperar la evidencia final.
    • Diferenciar entre indicio de edición y prueba de manipulación visual.

    Reglas

    No se proporciona una lista cerrada de herramientas. Cada decisión debe quedar documentada con comandos, capturas, resultados y nivel de confianza.

    El informe deberá incluir:

    1. Hash SHA-256 del archivo recibido.
    2. Análisis visual y OCR.
    3. Geolocalización razonada con al menos tres evidencias.
    4. Línea temporal y análisis de zona horaria.
    5. Inventario de bloques o chunks del PNG.
    6. Metadatos y cadenas encontradas.
    7. Análisis de esteganografía por canales y planos de bits.
    8. Búsqueda de firmas de archivos incrustados o anexados.
    9. Recuperación del código final.
    10. Separación entre hechos, hipótesis y pistas engañosas.

    No se considerará completa la práctica si únicamente se identifica la ciudad. El objetivo es reconstruir todas las capas del archivo.

  • Proyecto: Operación HAWKINS

    Proyecto: Operación HAWKINS

    Diseño de una infraestructura empresarial con VLSM y servicios de red

    1. Introducción

    Audio presentación

    El Centro de Investigación Avanzada de Hawkins es una organización ficticia inspirada en la serie Stranger Things. Tras varios incidentes en sus instalaciones, la dirección ha decidido sustituir su red improvisada por una infraestructura profesional, segmentada, documentada y preparada para crecer.

    El centro está formado por tres ubicaciones:

    • Sede Central de Hawkins: oficinas, laboratorios, seguridad, servidores y zona de visitantes.
    • Estación de Campo Starcourt: pequeño centro remoto de observación y comunicaciones.
    • Búnker NINA: instalación aislada en la que se realizan pruebas especialmente sensibles.

    Vuestro equipo ha sido contratado como consultora de sistemas y redes. Tendréis que analizar las necesidades de la organización, diseñar el direccionamiento mediante VLSM, construir una maqueta funcional y desplegar varios servicios de red.

    No se valorará únicamente que los equipos puedan comunicarse. La empresa exige una solución lógica, segura, ampliable, comprobada y correctamente documentada.


    2. Modalidad de trabajo

    • Trabajo individual o en parejas, según indique el profesor.
    • Herramienta principal recomendada: Cisco Packet Tracer.
    • Red IPv4 asignada a todo el proyecto: 172.20.0.0/16.
    • Todos los cálculos de subnetting deberán realizarse manualmente y explicarse además de mostrar las tablas completas.
    • En Packet Tracer no es necesario colocar físicamente todos los dispositivos indicados. Se representará cada red con un número reducido de equipos, pero el direccionamiento deberá admitir la cantidad real solicitada.
    • No es necesario realizar la configuración en los routers y switch, aunque si debe estar bien explicado en la documentación.

    3. Objetivos de aprendizaje

    Al terminar el proyecto, el alumnado deberá ser capaz de:

    1. Analizar las necesidades de una infraestructura con varias sedes.
    2. Crear subredes de distinto tamaño mediante VLSM.
    3. Calcular direcciones de red, broadcast, rangos utilizables y máscaras.
    4. Organizar departamentos mediante redes o VLAN independientes.
    5. Configurar direccionamiento estático y dinámico.
    6. Permitir la comunicación entre redes mediante routing.
    7. Aplicar reglas básicas de segmentación y control de acceso.
    8. Verificar el funcionamiento mediante pruebas reproducibles.
    9. Elaborar documentación técnica en Markdown.

    4. Historia del proyecto

    La infraestructura antigua utilizaba una única red para empleados, cámaras, servidores y visitantes. Esto ha provocado direcciones duplicadas, dificultad para localizar averías y acceso de usuarios no autorizados a recursos internos.

    La nueva red recibirá el nombre HAWKNET. Cada departamento deberá disponer de su propia subred. Las tres sedes estarán conectadas mediante enlaces WAN y compartirán determinados servicios alojados en la sede central.

    La dirección establece cuatro prioridades:

    • separar el tráfico de los departamentos;
    • garantizar que los nombres internos se resuelvan mediante DNS;
    • proporcionar configuración automática a los puestos de usuario;
    • proteger los laboratorios y la red de gestión frente a visitantes y dispositivos IoT.

    5. Topología general requerida

    La maqueta deberá contener, como mínimo:

    • un router o dispositivo de capa 3 en cada sede;
    • switches suficientes para representar la segmentación solicitada;
    • un switch principal en la sede central;
    • enlaces troncales cuando se utilicen VLAN;
    • un enlace entre la sede central y Starcourt;
    • un enlace entre la sede central y el búnker NINA;
    • servidores centralizados en Hawkins;
    • al menos un equipo cliente representativo en cada subred;
    • una nube o router ISP que represente Internet;
    • puntos de acceso inalámbricos para empleados y visitantes.

    El diseño exacto queda a criterio del equipo, pero todas las decisiones deberán justificarse.


    6. Necesidades de direccionamiento

    Se utilizará la red 172.20.0.0/16. A partir de ella debéis crear todas las subredes necesarias mediante VLSM.

    Las cantidades representan la capacidad que debe soportar cada red, no el número de dispositivos que hay que insertar en Packet Tracer.

    6.1. Sede Central de Hawkins

    Red o departamentoDispositivos actualesCrecimiento mínimo previsto
    Sensores, puertas y dispositivos IoT85020 %
    Wi-Fi de visitantes42020 %
    Personal administrativo19020 %
    Laboratorio de Energía11020 %
    Videovigilancia y seguridad física7520 %
    Investigadores6020 %
    Centro de Operaciones4220 %
    Servidores internos2620 %
    Telefonía IP2420 %
    Administración de red1220 %

    6.2. Estación de Campo Starcourt

    Red o departamentoDispositivos actualesCrecimiento mínimo previsto
    Personal de operaciones4820 %
    Sensores y cámaras3020 %
    Invitados1820 %
    Administración de red620 %

    6.3. Búnker NINA

    Red o departamentoDispositivos actualesCrecimiento mínimo previsto
    Laboratorio restringido2820 %
    Seguridad1420 %
    Servidores locales620 %
    Administración de red520 %

    6.4. Enlaces entre routers

    Debéis reservar una subred independiente para cada uno de estos enlaces:

    • Hawkins ↔ Starcourt.
    • Hawkins ↔ NINA.
    • Hawkins ↔ ISP.

    Cada enlace solo necesita las direcciones imprescindibles para sus dos extremos. Deberéis decidir si usar /30 o /31 y comprobar si la opción elegida es compatible con el simulador y los dispositivos utilizados.


    7. Normas para realizar el VLSM

    1. Calculad la capacidad necesaria sumando el crecimiento del 20 % y redondeando siempre hacia arriba.
    2. Recordad incluir las direcciones que vayan a consumir puertas de enlace, servidores u otros dispositivos de infraestructura.
    3. Ordenad las redes desde la que necesita más direcciones hasta la que necesita menos.
    4. Asignad a cada red el bloque más pequeño que cubra su necesidad.
    5. No pueden existir subredes solapadas.
    6. No debe desperdiciarse un bloque excesivamente grande sin una justificación técnica.
    7. La primera dirección utilizable de cada LAN se asignará, salvo justificación, a su puerta de enlace.
    8. Los servidores, routers, switches gestionables e impresoras usarán direcciones estáticas.
    9. Los clientes de usuario recibirán su configuración mediante DHCP.

    Para cada subred debéis mostrar el razonamiento utilizado. No será suficiente entregar una tabla generada automáticamente.


    8. Tabla obligatoria de direccionamiento

    La documentación incluirá una tabla como la siguiente, completada para todas las redes:

    SedeRed/VLANNecesidad con crecimientoPrefijoMáscara decimalDirección de redPrimer hostÚltimo hostBroadcastGateway
    HawkinsIoT

    También se añadirá una segunda tabla para los dispositivos configurados:

    DispositivoInterfazDirección IPMáscara/prefijoGatewayDNSAsignación
    SRV-DNS-01Fa0Estática

    9. VLAN y segmentación

    En la sede central cada departamento deberá estar separado mediante una VLAN o interfaz física diferente. Si se utilizan VLAN, debéis:

    • asignar un identificador y un nombre descriptivo a cada VLAN;
    • configurar los puertos de acceso;
    • utilizar una VLAN de gestión distinta de la VLAN nativa;
    • documentar qué puertos pertenecen a cada VLAN.

    Los identificadores de VLAN son libres, pero deben seguir un criterio coherente. Por ejemplo, se pueden agrupar por sede o por tipo de servicio.


    10. Routing entre sedes

    Todos los routers deberán conocer las redes remotas. El equipo elegirá una de estas opciones:

    El fallo de una ruta no podrá ocultarse añadiendo rutas innecesarias o utilizando una única red sin segmentación.


    11. Servicios obligatorios

    La red de servidores y las redes de administración no utilizarán DHCP para sus dispositivos principales.

    11.2. DNS

    El dominio interno será:

    hawkins.lab

    El DNS deberá contener, al menos, estos registros:

    11.3. Servidor web e intranet

    El servidor web mostrará una página sencilla con:

    • nombre y logotipo ficticio de la organización;
    • estado de las tres sedes;
    • mensaje de bienvenida;
    • nombre de los integrantes del equipo;
    • fecha de la última comprobación.

    La web pública de pruebas podrá ser accesible desde todas las redes. La intranet solo deberá ser accesible desde redes internas autorizadas.


    12. Requisitos básicos de seguridad

    La segmentación debe traducirse en reglas de acceso. Se configurarán ACL u otro mecanismo equivalente para cumplir, como mínimo, estas políticas:

    1. La red de visitantes solo puede acceder al DNS necesario, al portal web y a Internet.
    2. Los visitantes no pueden iniciar conexiones hacia las redes internas.
    3. La red IoT no puede acceder a Administración de red ni a los equipos de investigadores.
    4. Solo Administración de red puede gestionar routers y switches mediante SSH.
    5. Telnet deberá permanecer deshabilitado.
    6. El laboratorio NINA no será accesible desde redes de invitados.
    7. Seguridad podrá consultar las cámaras y sensores de las tres sedes.
    8. Los servidores DNS, DHCP y correo deberán ser accesibles únicamente desde las redes que necesiten cada servicio.

    Las reglas se colocarán lo más cerca posible del origen o destino y se documentará el motivo de cada una.


    13. Acceso a Internet y NAT

    La sede central se conectará a un router ISP. Debéis configurar:

    • una ruta por defecto hacia el ISP;
    • NAT/PAT para que las redes privadas autorizadas puedan salir a Internet;
    • un servidor externo de prueba, por ejemplo www.vecna-news.net, situado en una red que no pertenezca a 172.20.0.0/16;
    • bloqueo de salida para las redes que, según vuestra política, no deban acceder a Internet.

    No es necesario publicar servidores internos mediante NAT estático, aunque puede realizarse como ampliación.


    14. Nombres y configuración de dispositivos

    Los nombres deberán permitir identificar su ubicación y función. Ejemplos:

    RTR-HAW-01
    RTR-STAR-01
    RTR-NINA-01
    SW-HAW-CORE-01
    SW-HAW-LAB-01
    SRV-HAW-DNS-01
    PC-STAR-OPS-01

    15. Fases de realización

    Fase 1. Análisis

    1. Leed el caso completo.
    2. Identificad las sedes, departamentos, servidores y enlaces.
    3. Dibujad un primer esquema lógico.
    4. Decidid qué servicios serán centrales y cuáles serán locales.
    5. Anotad las restricciones de seguridad.

    Fase 2. Cálculo VLSM

    1. Calculad el número de hosts con crecimiento.
    2. Ordenad las redes de mayor a menor.
    3. Determinad el prefijo mínimo de cada una.
    4. Asignad los bloques dentro de 172.20.0.0/16.
    5. Calculad red, primer host, último host y broadcast.
    6. Comprobad que no existen solapamientos.
    7. Reservad espacio para futuras ampliaciones.

    Fase 3. Construcción de la topología

    1. Colocad routers, switches, servidores y clientes.
    2. Cablead correctamente los dispositivos.
    3. Asignad nombres a todos los equipos.
    4. Cread VLAN y configurad puertos.
    5. Configurad puertas de enlace.

    Fase 4. Direccionamiento y routing

    1. Configurad interfaces y subinterfaces.
    2. Asignad direcciones estáticas a infraestructura.
    3. Configurad rutas estáticas u OSPF.

    Fase 5. Pruebas y documentación

    1. Ejecutad el plan de pruebas.
    2. Corregid los fallos encontrados.
    3. Capturad evidencias relevantes.
    4. Completad el README.md.
    5. Revisad que otra persona pueda comprender y reproducir el proyecto.

    No se considerará demostrada una política si únicamente se prueba el caso permitido. Cuando corresponda, deberán probarse tanto el acceso correcto como su bloqueo.


    17. Entregables

    La entrega contendrá una carpeta comprimida con esta estructura orientativa:

    operacion-hawkins/
    ├── README.md
    ├── packet-tracer/
    │   └── hawknet.pkt
    ├── configuraciones/
    │   ├── RTR-HAW-01.txt
    │   ├── RTR-STAR-01.txt
    │   └── RTR-NINA-01.txt
    ├── diagramas/
    │   ├── topologia-logica.png
    │   └── topologia-fisica.png
    

    El archivo principal se llamará exactamente README.md y utilizará Markdown. Más adelante, cuando se haya trabajado Git, el mismo proyecto deberá poder incorporarse a un repositorio sin reorganizar toda la documentación.


    18. Contenido obligatorio del README.md

    1. Portada: título, integrantes, curso y fecha.
    2. Resumen ejecutivo del proyecto.
    3. Descripción de las tres sedes.
    4. Requisitos detectados.
    5. Diagrama lógico de red.
    6. Explicación paso a paso del cálculo VLSM.
    7. Tabla completa de direccionamiento.
    8. Tabla de VLAN.
    9. Inventario y función de los dispositivos.
    10. Explicación del routing seleccionado.
    11. Reglas de seguridad y ACL aplicadas.
    12. Configuración de NAT/PAT.
    13. Plan de pruebas y resultados.
    14. Problemas encontrados y soluciones.
    15. Conclusiones y posibles mejoras.
    16. Fuentes consultadas.

    Las capturas deben estar recortadas, ser legibles y llevar un pequeño texto explicativo. No se admitirán decenas de capturas sin contexto ni configuraciones pegadas sin explicación.


    19. Condiciones de aceptación

    El proyecto se considerará funcional cuando:

    • todas las subredes estén calculadas correctamente;
    • no haya direcciones duplicadas ni bloques solapados;
    • la comunicación entre sedes funcione;
    • los nombres internos se resuelvan mediante DNS;
    • los servicios obligatorios sean accesibles desde las redes autorizadas;
    • los accesos prohibidos sean realmente bloqueados;
    • el acceso exterior utilice NAT/PAT;
    • las pruebas estén documentadas;
    • el archivo de Packet Tracer se abra sin errores;
    • el README permita entender el trabajo sin una explicación oral adicional.

    Un proyecto en el que “todo puede comunicarse con todo” no cumplirá los requisitos de segmentación y seguridad.


    Las ampliaciones solo puntuarán si la parte obligatoria funciona y están correctamente explicadas.


    20. Penalizaciones importantes

    • Subredes solapadas o uso incorrecto de red/broadcast.
    • Archivo .pkt que no abre o que no coincide con la documentación.
    • Capturas de pantalla ajenas o configuraciones copiadas que el equipo no pueda explicar.
    • Uso de una sola red para evitar el trabajo de VLSM.

    21. Defensa del proyecto

    El profesor podrá seleccionar al azar cualquier dispositivo o prueba. El equipo tendrá que:

    Todos los integrantes deben conocer el proyecto completo. La división de tareas no exime de comprender el trabajo de la otra persona.


    23. Pregunta final de reflexión

    Incluid al final del README una respuesta razonada a estas cuestiones:

    • ¿Qué ventajas ofrece VLSM frente a utilizar la misma máscara en todas las redes?
    • ¿Qué ocurriría si empleados, servidores, cámaras y visitantes compartieran la misma red?
    • ¿Qué servicio causaría un impacto mayor si dejara de funcionar: DHCP, DNS o routing? Justificad la respuesta según vuestra infraestructura.
    • ¿Qué parte del diseño cambiaríais si la empresa duplicara su tamaño?

    Misión

    La red de Hawkins no debe limitarse a “tener pings”. Debe ser una infraestructura organizada, útil y defendible. Vuestro objetivo es demostrar que podéis convertir las necesidades de una organización en un diseño IP correcto, desplegar los servicios básicos y verificar que cada usuario accede únicamente a los recursos que necesita.

  • Proyecto: despliegue, ampliación y documentación de un servidor web con Ubuntu

    Proyecto: despliegue, ampliación y documentación de un servidor web con Ubuntu

    1. Presentación de la actividad

    Audio de introducción

    En esta actividad vas a desplegar y configurar un servidor web con Ubuntu siguiendo tres recursos proporcionados por el profesor. El objetivo no es limitarse a copiar comandos y realizar capturas de pantalla. Deberás comprender lo que haces, comprobar que cada elemento funciona y crear una documentación técnica que permita a otra persona repetir el proceso.

    El trabajo se desarrollará en tres partes consecutivas:

    1. Montaje del servidor web con Ubuntu.
    2. Ampliación UFW
    3. Configuración de Apache mediante archivos .htaccess.

    Cada parte amplía la anterior. Al terminar tendrás un único servidor funcional y un único documento técnico que describa todo el proyecto desde la preparación del entorno hasta las pruebas finales.

    2. Recursos obligatorios

    Debes seguir los tres recursos en el orden indicado. Puedes consultar otras fuentes para resolver problemas o ampliar las explicaciones, pero deberás citarlas en el apartado de referencias.

    3. Objetivos de aprendizaje

    Al finalizar la actividad deberás ser capaz de:

    • Preparar un sistema Ubuntu para funcionar como servidor.
    • Instalar, configurar y comprobar los servicios solicitados.
    • Identificar la función de los principales archivos, directorios, módulos, usuarios, permisos y puertos utilizados.
    • Aplicar configuraciones de Apache y comprobar sus efectos.
    • Interpretar los resultados de comandos de diagnóstico.
    • Detectar errores frecuentes y documentar su solución.
    • Valorar los riesgos de seguridad de una configuración.
    • Redactar documentación técnica clara y reproducible utilizando Markdown.
    • Organizar evidencias sin convertir el documento en una sucesión de capturas.
    • Preparar el proyecto para publicarlo posteriormente en un repositorio Git.

    4. Resultado que debes conseguir

    Debes disponer de un servidor Ubuntu desde el que se puedan demostrar las configuraciones solicitadas en las tres partes. Además, entregarás una documentación técnica completa en un archivo llamado exactamente:

    README.md

    La extensión correcta es .md, no .me. El archivo se escribirá con sintaxis Markdown.

    La documentación debe ser una ampliación razonada de los materiales. Esto significa que no debes copiar literalmente las explicaciones del profesor. Tienes que describir el proceso con tus propias palabras, explicar qué hace cada elemento importante y aportar pruebas de funcionamiento.

    5. Modalidad de realización

    • La actividad será individual, salvo que el profesor indique expresamente otra modalidad.
    • Cada estudiante deberá utilizar su propia máquina virtual o servidor asignado.
    • No se compartirán archivos README.md, capturas ni textos entre compañeros.
    • Sí se permite ayudar a localizar un error, siempre que cada estudiante comprenda y documente su propia solución.

    6. Preparación antes de comenzar

    Antes de modificar el servidor, anota en tu documentación:

    • Sistema de virtualización o equipo empleado.
    • Versión de Ubuntu.
    • Nombre de host.
    • Dirección IP del servidor.
    • Tipo de red de la máquina virtual: NAT, puente, red interna u otra.
    • Recursos asignados: CPU, memoria RAM y disco.
    • Dirección IP o nombre del equipo cliente desde el que realizarás las pruebas.

    Incluye una tabla similar a esta, completada con tus datos reales:

    ElementoConfiguración utilizada
    Sistema operativoUbuntu Server …
    Nombre del servidor
    Dirección IP
    CPU y RAM
    Disco
    Tipo de red
    Equipo cliente

    Recomendación previa

    Si trabajas con una máquina virtual, crea una instantánea antes de comenzar cada parte. Así podrás volver al estado anterior si una configuración deja el servidor inaccesible. Anota en el README.md cuándo has creado esas instantáneas.

    Protección de datos

    No incluyas en la entrega:

    • Contraseñas reales.
    • Claves privadas.
    • Tokens o credenciales.
    • Cookies o sesiones del Campus Virtual.
    • Direcciones públicas o datos personales que no sean necesarios.

    Oculta estos datos en las capturas. Utiliza valores de ejemplo cuando expliques credenciales.

    7. Parte 1: montaje del servidor web con Ubuntu

    Sigue el recurso de la parte 1 y documenta el proceso. Tu explicación deberá incluir, como mínimo, los siguientes bloques cuando aparezcan en el procedimiento realizado:

    7.1 Preparación del sistema

    Documenta la actualización del sistema y cualquier paquete previo necesario.

    Para cada comando importante:

    1. Escríbelo en un bloque de código.
    2. Explica qué hace.
    3. Describe las opciones o parámetros utilizados.
    4. Indica el resultado esperado.
    5. Añade una comprobación objetiva.

    Ejemplo del nivel de explicación esperado:

    sudo systemctl status apache2

    Este comando consulta el estado del servicio Apache. En la salida se debe comprobar que aparece como activo y en ejecución. No es suficiente con escribir «funciona»: hay que indicar qué dato de la salida permite afirmarlo.

    7.2 Instalación y prueba de Apache

    Debes explicar:

    • Qué es Apache y qué función cumple en el proyecto.
    • Qué paquete se instala.
    • Cómo se inicia, detiene, reinicia y consulta el servicio.
    • Qué directorio contiene inicialmente el sitio web.
    • Qué puerto utiliza HTTP.
    • Cómo accedes desde el equipo cliente.
    • Cómo compruebas el servicio desde terminal y desde navegador.

    Incluye una página web propia de prueba. No entregues únicamente la página predeterminada de Apache. La página debe mostrar, al menos, tu nombre, el título del proyecto y una indicación de que el servidor está operativo.

    7.3 Acceso remoto y transferencia de archivos

    Documenta los métodos de acceso o transferencia indicados en el recurso. Explica:

    • Qué servicio o programa interviene.
    • Qué puerto utiliza.
    • Qué usuario empleas y a qué directorio puede acceder.
    • Qué permisos has configurado.
    • Cómo has transferido o editado un archivo del sitio.
    • Cómo has verificado que el cambio aparece en el navegador.

    Si se utiliza FTP, añade una breve valoración de seguridad: diferencia entre FTP sin cifrar y alternativas como SFTP. No publiques credenciales reales.

    7.4 PHP

    Si el procedimiento incluye PHP, documenta:

    • Paquetes instalados y función de cada uno.
    • Versión instalada.
    • Integración con Apache.
    • Creación y ejecución de una página PHP de prueba.
    • Diferencia entre ejecutar PHP desde el servidor web y desde la terminal.

    Si utilizas una página con phpinfo(), elimínala o restríngele el acceso al finalizar, ya que puede mostrar información sensible del servidor. Explica esta decisión en el documento.

    7.5 Acceso mediante SSH o Visual Studio Code

    Si realizas este apartado, incluye:

    • Herramientas empleadas.
    • Configuración de la conexión sin mostrar contraseñas o claves privadas.
    • Directorio remoto abierto.
    • Prueba de edición de un archivo.
    • Evidencia del resultado servido por Apache.

    7.6 Comprobación de la parte 1

    Antes de continuar, verifica al menos:

    • El servidor responde a través de la red.
    • Apache está activo.
    • La página propia se carga desde el cliente.
    • Los archivos se encuentran en el directorio correcto.
    • PHP funciona, si forma parte del procedimiento.
    • El acceso remoto o la transferencia funciona, si se ha configurado.

    Incluye una tabla de pruebas:

    PruebaComando o acciónResultado esperadoResultado obtenidoEstado
    Estado de Apachesystemctl status apache2Servicio activoSuperada/No superada
    Acceso webAbrir http://IP_SERVIDORCarga la web propia
    Prueba de PHPAbrir la URL de pruebaPHP genera la respuesta

    8. Parte 2: ampliación del Campus Virtual

    Accede al recurso de la parte 2 con tu cuenta del Campus Virtual y realiza todos los pasos en el orden indicado.

    Como este bloque amplía el servidor de la parte 1, comienza explicando:

    • Qué nueva necesidad resuelve.
    • Qué servicio, componente o configuración añade.
    • Qué requisitos de la parte 1 necesita.
    • Qué cambios producirá en el servidor.

    Documentación obligatoria de cada paso

    Para cada acción relevante de la guía del campus incluye:

    1. Objetivo del paso. Qué se pretende conseguir.
    2. Comando o configuración. Escrito con el lenguaje correcto en un bloque de código.
    3. Explicación. Qué hace y por qué es necesario.
    4. Archivo afectado. Ruta completa y fragmento modificado, si corresponde.
    5. Comprobación. Comando, petición, acceso desde navegador o prueba equivalente.
    6. Resultado. Qué ocurrió realmente en tu servidor.
    7. Incidencia. Error encontrado y solución aplicada, si la hubo.

    No copies el texto completo del Campus Virtual. Reescribe el procedimiento con tus propias palabras y conserva únicamente los comandos, rutas y fragmentos de configuración necesarios.

    Comprobación de la parte 2

    Crea una tabla con todas las pruebas solicitadas por la guía. Debe quedar claro qué evidencia demuestra que la ampliación funciona y cómo podría repetirla otra persona.

    9. Parte 3: configuración de .htaccess en Apache

    Realiza la práctica de la parte 3 sobre el servidor ya configurado. Antes de empezar, crea una copia de seguridad de los archivos que vayas a modificar y documenta cómo podrías restaurarlos.

    9.1 Activación de .htaccess

    Explica:

    • Qué es un archivo .htaccess.
    • En qué directorios puede actuar.
    • Qué función cumple la directiva AllowOverride.
    • Qué diferencia existe entre AllowOverride None y AllowOverride All.
    • Qué archivo de Apache has modificado.
    • Cómo has validado la configuración antes de reiniciar o recargar el servicio.
    • Cómo has comprobado que Apache continúa funcionando.

    9.2 Autenticación básica

    Configura una zona restringida y documenta:

    • Directorio protegido.
    • Creación del archivo de usuarios.
    • Directivas de autenticación utilizadas.
    • Prueba sin autenticar, con credenciales incorrectas y con credenciales correctas.
    • Código de estado HTTP o comportamiento observado en cada caso.

    No muestres la contraseña. Investiga y explica por qué la autenticación básica debería utilizarse junto con HTTPS y por qué es preferible guardar .htpasswd fuera del directorio público cuando sea posible.

    9.3 Páginas de error personalizadas

    Crea páginas propias para los errores solicitados, por ejemplo 403 y 404. Las páginas deberán tener un diseño mínimo coherente con tu sitio.

    Comprueba cada error provocándolo de forma controlada e indica:

    • URL o acción de prueba.
    • Código esperado.
    • Código recibido.
    • Página mostrada.

    9.4 Cabeceras de seguridad

    Aplica las cabeceras propuestas en la práctica y crea una tabla como esta:

    CabeceraValor aplicadoRiesgo que ayuda a reducirMétodo de comprobación
    X-Frame-Options
    X-Content-Type-Options
    Referrer-Policy
    Permissions-Policy

    Comprueba las cabeceras con las herramientas de desarrollo del navegador o con una petición de terminal, no solo mediante una captura del archivo de configuración.

    Si el recurso incluye una cabecera considerada antigua o desaconsejada por navegadores actuales, indícalo en tu análisis y explica qué mecanismo moderno se utiliza en su lugar. Esta observación deberá estar respaldada por una fuente técnica.

    9.5 Redirecciones

    Configura y prueba las redirecciones solicitadas. Explica la diferencia entre una redirección permanente y una temporal, incluyendo:

    • Código de estado.
    • Efecto para el navegador.
    • Posible efecto en caché.
    • Uso habitual.
    • Implicaciones generales para buscadores.

    Incluye una prueba donde se puedan observar la respuesta y el destino final.

    9.6 Reescritura de URLs

    Si la guía utiliza mod_rewrite, explica:

    • Qué problema resuelve.
    • Diferencia entre redirección y reescritura interna.
    • Módulo necesario.
    • Significado de la regla aplicada.
    • URL escrita por el usuario y recurso procesado realmente.

    Debes demostrar el funcionamiento con al menos un ejemplo propio diferente del ejemplo literal de la guía.

    9.7 Resto de configuraciones del recurso

    Completa también las configuraciones adicionales incluidas en la guía, como control de indexación, protección u ocultación de recursos, caché o compresión, cuando aparezcan en el procedimiento. Para cada una explica el objetivo, la configuración aplicada, la prueba realizada y su resultado.

    9.8 Comprobación de la parte 3

    Prepara una tabla final de pruebas que incluya, como mínimo:

    • Acceso a la zona restringida.
    • Error 403.
    • Error 404.
    • Cabeceras de seguridad.
    • Redirección temporal.
    • Redirección permanente.
    • Reescritura de URL.
    • Resto de funcionalidades realizadas.

    10. Ampliaciones técnicas obligatorias

    Tu trabajo no debe ser una reproducción literal de los enlaces. Añade las siguientes ampliaciones:

    Ampliación A: mapa del sistema

    Incluye un diagrama Mermaid que muestre, al menos, el equipo cliente, el servidor Ubuntu, Apache y los componentes principales instalados. Ejemplo de sintaxis:

    flowchart LR
        A[Cliente] -->|HTTP| B[Apache en Ubuntu]
        B --> C[Sitio web]
        B --> D[PHP]

    Adapta el diagrama a tu instalación real. No copies el ejemplo sin modificarlo.

    Ampliación B: relación de puertos y servicios

    Incluye una tabla con los servicios utilizados, sus puertos, protocolo de transporte, finalidad y estado final. Si un puerto no debe quedar accesible, explícalo.

    Ampliación C: seguridad

    Identifica al menos cinco riesgos o decisiones de seguridad observados durante las tres partes. Para cada uno indica:

    • Riesgo.
    • Configuración relacionada.
    • Consecuencia posible.
    • Medida de mejora.
    • Prioridad: baja, media o alta.

    Ampliación D: diagnóstico

    Incluye una pequeña guía de resolución de problemas con un mínimo de cinco incidencias. Pueden ser errores que hayas encontrado o errores razonables que hayas reproducido de forma segura.

    SíntomaPosible causaComprobaciónSolución
    Apache no arrancaError de sintaxis
    La web no responde desde el cliente

    Ampliación E: comandos de comprobación

    Crea una sección de consulta rápida con los comandos que permitan comprobar el estado del servidor. No basta con enumerarlos: añade una frase que explique qué verifica cada uno.

    11. Estructura obligatoria del README.md

    El documento deberá contener, como mínimo, esta estructura:

    # Despliegue y ampliación de un servidor web con Ubuntu
    
    ## 1. Autor y datos de la práctica
    ## 2. Resumen del proyecto
    ## 3. Objetivos
    ## 4. Entorno y requisitos
    ## 5. Esquema de la infraestructura
    ## 6. Parte 1: montaje del servidor web
    ## 7. Parte 2: ampliación del Campus Virtual
    ## 8. Parte 3: configuración de .htaccess
    ## 9. Pruebas finales
    ## 10. Problemas encontrados y soluciones
    ## 11. Análisis de seguridad
    ## 12. Conclusiones
    ## 13. Referencias

    Puedes añadir subsecciones, pero no eliminar las anteriores.

    12. Requisitos de formato Markdown

    En el README.md deberás utilizar correctamente:

    • Títulos y subtítulos con #, ## y ###.
    • Párrafos breves y explicativos.
    • Listas numeradas y no numeradas.
    • Tablas.
    • Enlaces con texto descriptivo.
    • Imágenes con texto alternativo.
    • Bloques de código indicando el lenguaje: bash, apache, html, php, etc.
    • Código corto entre comillas invertidas.
    • Avisos o notas mediante citas >.
    • Al menos un diagrama Mermaid.
    • Índice con enlaces internos si el documento es largo.

    No utilices capturas para mostrar texto que puede copiarse, como comandos o configuraciones. Escríbelo en bloques de código y reserva las imágenes para demostrar resultados visuales relevantes.

    13. Capturas y evidencias

    Guarda las imágenes en una carpeta llamada img y utiliza nombres descriptivos:

    img/01-apache-activo.png
    img/02-web-desde-cliente.png
    img/03-zona-restringida.png
    img/04-error-404.png

    Insértalas con rutas relativas:

    ![Apache activo en el servidor](img/01-apache-activo.png)

    Cada evidencia debe cumplir estas condiciones:

    • Tener relación directa con una prueba.
    • Ser legible.
    • Mostrar solo la información necesaria.
    • Tener una explicación antes o después de la imagen.
    • Ocultar contraseñas, tokens y otros datos sensibles.
    • No repetir varias capturas que demuestren exactamente lo mismo.

    14. Organización de la entrega

    La carpeta deberá tener una estructura similar a esta:

    apellido-nombre-servidor-web/
    ├── README.md
    ├── img/
    │   ├── 01-apache-activo.png
    │   ├── 02-web-desde-cliente.png
    │   └── ...
    ├── web/
    │   ├── index.html
    │   ├── 403.html
    │   ├── 404.html
    │   └── ...
    └── config/
        ├── htaccess.txt
        └── ...

    Los archivos de configuración se entregarán como copia para su revisión. Si un archivo debe llamarse .htaccess en el servidor, puedes conservar ese nombre dentro de la entrega o añadir una copia legible como htaccess.txt. Nunca incluyas archivos de contraseñas reales como .htpasswd.

    15. Entrega actual mediante ZIP

    Como todavía no hemos trabajado Git, en esta primera entrega comprime la carpeta completa en un archivo ZIP con este nombre:

    apellido-nombre-servidor-web.zip

    Antes de subirlo, descomprímelo en una carpeta temporal y comprueba que:

    • Existe README.md en la raíz.
    • El documento se abre correctamente.
    • Las imágenes se muestran usando rutas relativas.
    • Se incluyen los archivos web y las configuraciones necesarias.
    • No hay contraseñas ni datos sensibles.
    • No se incluyen discos virtuales, imágenes ISO, copias completas de la máquina virtual ni carpetas innecesarias.

    Sube el ZIP al espacio de entrega indicado por el profesor.

    16. Publicación posterior en Git

    La entrega mediante ZIP es provisional. Cuando estudiemos Git y GitHub, deberás publicar esta misma actividad en un repositorio.

    Por este motivo, organiza desde ahora el trabajo como si ya fuera un repositorio:

    • Un único README.md principal en la raíz.
    • Carpetas con nombres simples, sin espacios ni tildes.
    • Rutas relativas para imágenes y enlaces internos.
    • Archivos ordenados y con nombres descriptivos.
    • Ninguna contraseña o credencial guardada.
    • Un archivo .gitignore cuando aprendamos Git, si el proyecto lo necesita.

    Más adelante se valorará la evolución del documento mediante commits. No será válido crear el repositorio al final y subir todo sin mostrar el proceso de mejora cuando se explique esa parte de la asignatura.

    17. Defensa y comprobación por parte del profesor

    El profesor podrá solicitar que el estudiante:

    • Explique cualquier comando incluido.
    • Localice un archivo de configuración.
    • Reinicie o recargue un servicio.
    • Demuestre una de las pruebas.
    • Modifique una regla sencilla.
    • Interprete un error.
    • Justifique una decisión de seguridad.

    Una configuración que funciona pero que el estudiante no puede explicar se considerará incompleta.

    18. Criterios de evaluación

    CriterioPeso
    Parte 1: instalación, configuración y pruebas20 %
    Parte 2: realización, explicación y pruebas15 %
    Parte 3: .htaccess, seguridad y pruebas25 %
    Ampliaciones técnicas y capacidad de análisis15 %
    Calidad del README.md y uso de Markdown15 %
    Organización, evidencias, referencias y entrega10 %
    Total100 %

    Para obtener una valoración alta

    El documento debe permitir reproducir el proyecto, explicar el propósito de las configuraciones, incluir pruebas objetivas, analizar riesgos y mostrar capacidad para resolver problemas.

    Penalizaciones importantes

    Podrán reducir la calificación:

    • Copiar y pegar los recursos sin elaborar explicaciones propias.
    • Incluir comandos que no se han ejecutado o resultados inventados.
    • Presentar capturas sin explicación.
    • No demostrar el funcionamiento de una parte.
    • Utilizar rutas absolutas locales para las imágenes del README.md.
    • Entregar enlaces o imágenes rotos.
    • Exponer contraseñas o credenciales.
    • No respetar la estructura de la entrega.

    La ausencia de una de las tres partes impedirá considerar el proyecto completo.

    19. Lista de comprobación final del estudiante

    Antes de entregar, confirma cada punto:

    • He completado las tres partes.
    • Mi archivo principal se llama README.md.
    • He escrito las explicaciones con mis propias palabras.
    • Puedo explicar todos los comandos que aparecen.
    • He indicado mi entorno y configuración de red.
    • He incluido un diagrama Mermaid adaptado a mi instalación.
    • He realizado y documentado pruebas objetivas.
    • He añadido las ampliaciones técnicas obligatorias.
    • He documentado al menos cinco problemas o casos de diagnóstico.
    • He analizado al menos cinco aspectos de seguridad.
    • Las imágenes tienen nombres descriptivos y rutas relativas.
    • No he incluido contraseñas, claves ni datos sensibles.
    • Las referencias utilizadas aparecen citadas.
    • He comprobado el ZIP después de descomprimirlo.
    • La estructura está preparada para convertirla posteriormente en un repositorio Git.

    20. Idea clave de la actividad

    El resultado no es solo un servidor que funciona. El verdadero producto de este proyecto es una documentación técnica que demuestre qué has construido, por qué lo has configurado así, cómo sabes que funciona y cómo podría mantenerlo o reproducirlo otra pe

  • Proyecto web en PHP orientado a objetos: tienda de cuencos tibetanos

    Proyecto web en PHP orientado a objetos: tienda de cuencos tibetanos

    En este proyecto vamos a desarrollar una aplicación web completa utilizando PHP orientado a objetos, MySQL, HTML y CSS. La temática será una tienda online de cuencos tibetanos llamada Sonido Interior.

    Este proyecto es una evolución del proyecto inicial realizado con PHP básico. En la primera versión trabajamos con páginas PHP sencillas, formularios, includes, conexión directa a base de datos y consultas SQL escritas en cada archivo.

    En esta nueva versión vamos a dar un paso más importante: organizaremos el código mediante clases, separaremos responsabilidades y construiremos una estructura más cercana a la que se utiliza en aplicaciones web reales.

    El objetivo no es complicar el proyecto sin necesidad, sino aprender a programar de forma más ordenada, reutilizable y mantenible.


    1. Objetivo general del proyecto

    Vamos a crear una tienda web de cuencos tibetanos con una parte pública y una parte administrativa.

    La parte pública permitirá ver la página de inicio, consultar el catálogo de productos y visualizar información de la tienda.

    La parte administrativa permitirá iniciar sesión, añadir productos, listar productos, editar productos y borrar productos.

    La diferencia principal respecto a la versión anterior será la forma de organizar el código.

    En lugar de escribir toda la lógica directamente en archivos como producto-guardar.php, producto-editar.php o catalogo.php, crearemos clases encargadas de realizar esas tareas.

    Por ejemplo, tendremos clases como:

    • Producto
    • Categoria
    • Usuario
    • Conexion
    • ProductoDAO
    • CategoriaDAO
    • UsuarioDAO

    Con esto empezaremos a trabajar una arquitectura más limpia y profesional.


    2. Qué significa usar programación orientada a objetos

    La programación orientada a objetos, o POO, es una forma de programar basada en clases y objetos.

    Una clase es como un molde. Define qué datos tendrá un elemento y qué acciones podrá realizar.

    Un objeto es una instancia concreta de una clase.

    Por ejemplo, en nuestro proyecto podemos tener una clase Producto.

    Esa clase representa cualquier producto de la tienda.

    class Producto {
    private $idProducto;
    private $nombre;
    private $descripcion;
    private $precio;
    private $stock;
    private $imagen;
    }

    Después, un cuenco tibetano concreto sería un objeto de esa clase.

    $producto = new Producto();

    La ventaja de este enfoque es que el código queda mejor organizado. En lugar de trabajar con variables sueltas y consultas repartidas por muchas páginas, agrupamos la información y el comportamiento en clases.


    3. Diferencia entre la versión básica y la versión POO

    En la versión básica del proyecto, la conexión a la base de datos y las consultas pueden estar escritas directamente dentro de las páginas.

    Por ejemplo:

    include("includes/conexion.php");

    $sql = "SELECT * FROM productos";
    $resultado = $conexion->query($sql);

    En la versión orientada a objetos, intentaremos que la página no tenga que saber cómo se hace la consulta.

    La página pedirá los productos a una clase especializada:

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();

    La página solo se encargará de mostrar los datos. La clase ProductoDAO será la encargada de hablar con la base de datos.

    Esto hace que el proyecto sea más fácil de mantener, ampliar y corregir.


    4. Tecnologías que vamos a utilizar

    En esta versión seguiremos utilizando las mismas tecnologías principales:

    • HTML.
    • CSS.
    • PHP.
    • MySQL o MariaDB.
    • Apache.
    • phpMyAdmin.
    • Hosting o contenedor Docker.

    La diferencia es que en PHP trabajaremos con:

    • Clases.
    • Objetos.
    • Atributos.
    • Métodos.
    • Constructores.
    • Encapsulación.
    • Getters y setters.
    • Clases DAO.
    • Separación de responsabilidades.
    • Consultas preparadas.
    • Sesiones.
    • Autoload básico o includes de clases.

    5. Resultado final esperado

    Al finalizar esta versión del proyecto tendremos una aplicación web parecida a la anterior, pero con una organización interna mucho mejor.

    La aplicación incluirá:

    • Página de inicio.
    • Catálogo público de productos.
    • Página de login.
    • Zona administrativa.
    • Alta de productos.
    • Listado administrativo.
    • Edición de productos.
    • Borrado lógico de productos.
    • Subida de imagen por producto.
    • Conexión a base de datos mediante una clase.
    • Entidades representadas mediante clases.
    • Clases DAO para acceder a la base de datos.
    • Uso de sesiones para proteger la administración.
    • Código más limpio y reutilizable.

    Fases del proyecto

    Fase 1: repaso de la versión inicial

    Antes de empezar con la versión orientada a objetos, revisaremos brevemente la versión anterior del proyecto.

    Recordaremos cómo funcionaba:

    • Las páginas públicas.
    • Las páginas administrativas.
    • Los formularios.
    • Los includes.
    • La conexión a la base de datos.
    • Las consultas SELECT, INSERT, UPDATE y DELETE.
    • La subida de imágenes.
    • El login con sesiones.

    Esto es importante porque la versión POO no cambia la finalidad del proyecto. Lo que cambia es la forma de organizar el código.


    Fase 2: análisis de las clases necesarias

    El primer paso será pensar qué elementos importantes tiene nuestro proyecto.

    En una tienda de cuencos tibetanos podemos encontrar estos elementos:

    • Productos.
    • Categorías.
    • Usuarios administradores.
    • Mensajes de contacto.
    • Pedidos.
    • Detalles de pedido.
    • Carrito.
    • Imágenes.

    Cada uno de estos elementos puede representarse con una clase.

    Para empezar, trabajaremos con las clases principales:

    • Producto
    • Categoria
    • Usuario
    • Conexion

    Después añadiremos las clases encargadas de acceder a la base de datos:

    • ProductoDAO
    • CategoriaDAO
    • UsuarioDAO

    Fase 3: estructura de carpetas del proyecto

    En esta versión necesitaremos una estructura más organizada.

    Una posible estructura será esta:

    sonido-interior-poo/

    ├── index.php
    ├── catalogo.php
    ├── login.php
    ├── validar-login.php
    ├── logout.php

    ├── admin/
    │ ├── panel.php
    │ ├── productos.php
    │ ├── producto-alta.php
    │ ├── producto-guardar.php
    │ ├── producto-editar.php
    │ ├── producto-actualizar.php
    │ └── producto-borrar.php

    ├── includes/
    │ ├── header.php
    │ ├── menu.php
    │ ├── menu-admin.php
    │ ├── footer.php
    │ └── seguridad.php

    ├── clases/
    │ ├── Conexion.php
    │ ├── Producto.php
    │ ├── Categoria.php
    │ ├── Usuario.php
    │ ├── ProductoDAO.php
    │ ├── CategoriaDAO.php
    │ └── UsuarioDAO.php

    ├── css/
    │ └── estilos.css

    ├── img/
    │ └── productos/

    └── sql/
    └── tienda_cuencos.sql

    La carpeta más importante de esta versión será clases/.

    Ahí guardaremos las clases del proyecto.


    Fase 4: creación de la clase Conexion

    La primera clase que crearemos será Conexion.

    Esta clase se encargará de conectarse a la base de datos.

    En lugar de tener un archivo conexion.php con variables sueltas, crearemos una clase con un método que devuelva la conexión.

    Ejemplo:

    <?php

    class Conexion {

    private $servidor = "localhost";
    private $usuario = "root";
    private $password = "";
    private $baseDatos = "tienda_cuencos";

    public function conectar() {
    $conexion = new mysqli(
    $this->servidor,
    $this->usuario,
    $this->password,
    $this->baseDatos
    );

    if ($conexion->connect_error) {
    die("Error de conexión: " . $conexion->connect_error);
    }

    $conexion->set_charset("utf8");

    return $conexion;
    }
    }

    ?>

    Con esta clase podremos conectarnos a la base de datos desde cualquier DAO.

    Ejemplo:

    $conexionBD = new Conexion();
    $conexion = $conexionBD->conectar();

    Fase 5: creación de la clase Producto

    Después crearemos la clase Producto.

    Esta clase representará un producto de la tienda.

    Tendrá atributos privados como:

    • ID.
    • Nombre.
    • Descripción.
    • Precio.
    • Stock.
    • Imagen.
    • Diámetro.
    • Peso.
    • Material.
    • Nota musical.
    • Procedencia.
    • Activo.
    • Categoría.

    Ejemplo:

    <?php

    class Producto {

    private $idProducto;
    private $nombre;
    private $descripcion;
    private $precio;
    private $stock;
    private $imagen;
    private $diametro;
    private $peso;
    private $material;
    private $notaMusical;
    private $procedencia;
    private $activo;
    private $idCategoria;

    public function __construct(
    $idProducto = null,
    $nombre = "",
    $descripcion = "",
    $precio = 0,
    $stock = 0,
    $imagen = "",
    $diametro = 0,
    $peso = 0,
    $material = "",
    $notaMusical = "",
    $procedencia = "",
    $activo = true,
    $idCategoria = null
    ) {
    $this->idProducto = $idProducto;
    $this->nombre = $nombre;
    $this->descripcion = $descripcion;
    $this->precio = $precio;
    $this->stock = $stock;
    $this->imagen = $imagen;
    $this->diametro = $diametro;
    $this->peso = $peso;
    $this->material = $material;
    $this->notaMusical = $notaMusical;
    $this->procedencia = $procedencia;
    $this->activo = $activo;
    $this->idCategoria = $idCategoria;
    }

    public function getIdProducto() {
    return $this->idProducto;
    }

    public function getNombre() {
    return $this->nombre;
    }

    public function setNombre($nombre) {
    $this->nombre = $nombre;
    }

    public function getDescripcion() {
    return $this->descripcion;
    }

    public function setDescripcion($descripcion) {
    $this->descripcion = $descripcion;
    }

    public function getPrecio() {
    return $this->precio;
    }

    public function setPrecio($precio) {
    $this->precio = $precio;
    }

    public function getStock() {
    return $this->stock;
    }

    public function setStock($stock) {
    $this->stock = $stock;
    }
    }

    ?>

    Durante el proyecto iremos completando la clase con todos los getters y setters necesarios.


    Fase 6: creación de la clase Categoria

    La clase Categoria representará una categoría de producto.

    Ejemplo:

    <?php

    class Categoria {

    private $idCategoria;
    private $nombre;
    private $descripcion;
    private $activo;

    public function __construct(
    $idCategoria = null,
    $nombre = "",
    $descripcion = "",
    $activo = true
    ) {
    $this->idCategoria = $idCategoria;
    $this->nombre = $nombre;
    $this->descripcion = $descripcion;
    $this->activo = $activo;
    }

    public function getIdCategoria() {
    return $this->idCategoria;
    }

    public function getNombre() {
    return $this->nombre;
    }

    public function setNombre($nombre) {
    $this->nombre = $nombre;
    }

    public function getDescripcion() {
    return $this->descripcion;
    }

    public function setDescripcion($descripcion) {
    $this->descripcion = $descripcion;
    }

    public function getActivo() {
    return $this->activo;
    }

    public function setActivo($activo) {
    $this->activo = $activo;
    }
    }

    ?>

    Esta clase nos permitirá trabajar con categorías de forma ordenada.


    Fase 7: creación de la clase Usuario

    La clase Usuario representará a los usuarios administradores.

    Tendrá atributos como:

    • ID.
    • Nombre.
    • Email.
    • Usuario.
    • Password.
    • Rol.

    Ejemplo:

    <?php

    class Usuario {

    private $idUsuario;
    private $nombre;
    private $email;
    private $usuario;
    private $password;
    private $rol;

    public function __construct(
    $idUsuario = null,
    $nombre = "",
    $email = "",
    $usuario = "",
    $password = "",
    $rol = "admin"
    ) {
    $this->idUsuario = $idUsuario;
    $this->nombre = $nombre;
    $this->email = $email;
    $this->usuario = $usuario;
    $this->password = $password;
    $this->rol = $rol;
    }

    public function getIdUsuario() {
    return $this->idUsuario;
    }

    public function getNombre() {
    return $this->nombre;
    }

    public function getUsuario() {
    return $this->usuario;
    }

    public function getPassword() {
    return $this->password;
    }

    public function getRol() {
    return $this->rol;
    }
    }

    ?>

    Esta clase se usará principalmente para el login y la gestión de sesiones.


    Fase 8: qué es una clase DAO

    En esta versión del proyecto usaremos clases DAO.

    DAO significa Data Access Object, es decir, objeto de acceso a datos.

    Una clase DAO se encarga de hablar con la base de datos.

    Por ejemplo, la clase Producto representa los datos de un producto, pero no debería ser la encargada de hacer consultas SQL.

    Para eso tendremos ProductoDAO.

    La clase ProductoDAO tendrá métodos como:

    • obtenerTodos()
    • obtenerPorId($id)
    • crear($producto)
    • actualizar($producto)
    • eliminar($id)
    • disminuirStock($idProducto, $cantidad)

    La ventaja es que las consultas SQL quedan agrupadas en una clase concreta.


    Fase 9: creación de ProductoDAO

    La clase ProductoDAO será una de las más importantes del proyecto.

    Ejemplo inicial:

    <?php

    require_once "Conexion.php";
    require_once "Producto.php";

    class ProductoDAO {

    private $conexion;

    public function __construct() {
    $conexionBD = new Conexion();
    $this->conexion = $conexionBD->conectar();
    }

    public function obtenerTodos() {
    $sql = "SELECT * FROM productos WHERE activo = 1";
    $resultado = $this->conexion->query($sql);

    $productos = [];

    while ($fila = $resultado->fetch_assoc()) {
    $producto = new Producto(
    $fila["id_producto"],
    $fila["nombre"],
    $fila["descripcion"],
    $fila["precio"],
    $fila["stock"],
    $fila["imagen"],
    $fila["diametro"],
    $fila["peso"],
    $fila["material"],
    $fila["nota_musical"],
    $fila["procedencia"],
    $fila["activo"],
    $fila["id_categoria"]
    );

    $productos[] = $producto;
    }

    return $productos;
    }
    }

    ?>

    Ahora, desde catalogo.php, podremos obtener los productos así:

    require_once "clases/ProductoDAO.php";

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();

    Y después recorrerlos:

    foreach ($productos as $producto) {
    echo "<h3>" . $producto->getNombre() . "</h3>";
    echo "<p>" . $producto->getPrecio() . " €</p>";
    }

    Fase 10: mostrar el catálogo usando objetos

    En la página catalogo.php, ya no haremos directamente una consulta SQL.

    La página simplemente pedirá los productos a ProductoDAO.

    Ejemplo:

    <?php
    require_once "clases/ProductoDAO.php";
    include("includes/header.php");
    include("includes/menu.php");

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();
    ?>

    <main class="contenedor">
    <h1>Catálogo de productos</h1>

    <section class="grid-productos">
    <?php foreach ($productos as $producto): ?>
    <article class="tarjeta-producto">
    <img src="img/productos/<?php echo $producto->getImagen(); ?>" alt="<?php echo $producto->getNombre(); ?>">
    <h3><?php echo $producto->getNombre(); ?></h3>
    <p><?php echo $producto->getPrecio(); ?> €</p>
    </article>
    <?php endforeach; ?>
    </section>
    </main>

    <?php include("includes/footer.php"); ?>

    Para que esto funcione, la clase Producto deberá tener métodos como:

    • getImagen()
    • getNombre()
    • getPrecio()

    Fase 11: alta de productos usando objetos

    Cuando enviemos el formulario de alta, recogeremos los datos del formulario y crearemos un objeto Producto.

    Ejemplo en producto-guardar.php:

    require_once "../clases/Producto.php";
    require_once "../clases/ProductoDAO.php";

    $producto = new Producto();

    $producto->setNombre($_POST["nombre"]);
    $producto->setDescripcion($_POST["descripcion"]);
    $producto->setPrecio($_POST["precio"]);
    $producto->setStock($_POST["stock"]);
    $producto->setMaterial($_POST["material"]);
    $producto->setProcedencia($_POST["procedencia"]);

    $productoDAO = new ProductoDAO();
    $productoDAO->crear($producto);

    Después, dentro de ProductoDAO, tendremos el método crear().

    Ejemplo:

    public function crear($producto) {
    $sql = "INSERT INTO productos
    (nombre, descripcion, precio, stock, material, procedencia)
    VALUES (?, ?, ?, ?, ?, ?)";

    $stmt = $this->conexion->prepare($sql);

    $nombre = $producto->getNombre();
    $descripcion = $producto->getDescripcion();
    $precio = $producto->getPrecio();
    $stock = $producto->getStock();
    $material = $producto->getMaterial();
    $procedencia = $producto->getProcedencia();

    $stmt->bind_param(
    "ssdiss",
    $nombre,
    $descripcion,
    $precio,
    $stock,
    $material,
    $procedencia
    );

    return $stmt->execute();
    }

    Este enfoque es más limpio porque el archivo del formulario no contiene directamente toda la consulta SQL.


    Fase 12: listado administrativo usando objetos

    El listado administrativo también usará ProductoDAO.

    La página admin/productos.php pedirá todos los productos:

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();

    Después los mostrará en una tabla:

    <?php foreach ($productos as $producto): ?>
    <tr>
    <td><?php echo $producto->getIdProducto(); ?></td>
    <td><?php echo $producto->getNombre(); ?></td>
    <td><?php echo $producto->getPrecio(); ?> €</td>
    <td><?php echo $producto->getStock(); ?></td>
    <td>
    <a href="producto-editar.php?id=<?php echo $producto->getIdProducto(); ?>">Editar</a>
    <a href="producto-borrar.php?id=<?php echo $producto->getIdProducto(); ?>">Borrar</a>
    </td>
    </tr>
    <?php endforeach; ?>

    La página se centra en mostrar información, no en saber cómo se consulta la base de datos.


    Fase 13: obtener un producto por ID

    Para editar un producto necesitaremos recuperarlo por su ID.

    Añadiremos este método a ProductoDAO:

    public function obtenerPorId($id) {
    $sql = "SELECT * FROM productos WHERE id_producto = ?";
    $stmt = $this->conexion->prepare($sql);
    $stmt->bind_param("i", $id);
    $stmt->execute();

    $resultado = $stmt->get_result();

    if ($fila = $resultado->fetch_assoc()) {
    return new Producto(
    $fila["id_producto"],
    $fila["nombre"],
    $fila["descripcion"],
    $fila["precio"],
    $fila["stock"],
    $fila["imagen"],
    $fila["diametro"],
    $fila["peso"],
    $fila["material"],
    $fila["nota_musical"],
    $fila["procedencia"],
    $fila["activo"],
    $fila["id_categoria"]
    );
    }

    return null;
    }

    Después, desde producto-editar.php:

    $id = $_GET["id"];

    $productoDAO = new ProductoDAO();
    $producto = $productoDAO->obtenerPorId($id);

    Así podremos rellenar el formulario de edición con los datos actuales del producto.


    Fase 14: actualización de productos

    Cuando se envíe el formulario de edición, crearemos un objeto Producto con los datos actualizados.

    Después llamaremos al método actualizar() de ProductoDAO.

    Ejemplo:

    $producto = new Producto();

    $producto->setIdProducto($_POST["id_producto"]);
    $producto->setNombre($_POST["nombre"]);
    $producto->setDescripcion($_POST["descripcion"]);
    $producto->setPrecio($_POST["precio"]);
    $producto->setStock($_POST["stock"]);

    $productoDAO = new ProductoDAO();
    $productoDAO->actualizar($producto);

    El método actualizar() hará una consulta UPDATE.

    public function actualizar($producto) {
    $sql = "UPDATE productos
    SET nombre = ?, descripcion = ?, precio = ?, stock = ?
    WHERE id_producto = ?";

    $stmt = $this->conexion->prepare($sql);

    $nombre = $producto->getNombre();
    $descripcion = $producto->getDescripcion();
    $precio = $producto->getPrecio();
    $stock = $producto->getStock();
    $id = $producto->getIdProducto();

    $stmt->bind_param("ssdii", $nombre, $descripcion, $precio, $stock, $id);

    return $stmt->execute();
    }

    Fase 15: borrado lógico de productos

    En lugar de borrar físicamente un producto, lo marcaremos como inactivo.

    En ProductoDAO añadiremos un método eliminar():

    public function eliminar($id) {
    $sql = "UPDATE productos SET activo = 0 WHERE id_producto = ?";
    $stmt = $this->conexion->prepare($sql);
    $stmt->bind_param("i", $id);

    return $stmt->execute();
    }

    Desde producto-borrar.php:

    $id = $_GET["id"];

    $productoDAO = new ProductoDAO();
    $productoDAO->eliminar($id);

    header("Location: productos.php");
    exit();

    Con esto el producto seguirá en la base de datos, pero dejará de mostrarse en la tienda.


    Fase 16: gestión de categorías con CategoriaDAO

    Igual que tenemos ProductoDAO, crearemos CategoriaDAO.

    Esta clase tendrá métodos como:

    • obtenerTodas()
    • obtenerPorId($id)
    • crear($categoria)
    • actualizar($categoria)
    • eliminar($id)

    Ejemplo básico:

    <?php

    require_once "Conexion.php";
    require_once "Categoria.php";

    class CategoriaDAO {

    private $conexion;

    public function __construct() {
    $conexionBD = new Conexion();
    $this->conexion = $conexionBD->conectar();
    }

    public function obtenerTodas() {
    $sql = "SELECT * FROM categorias WHERE activo = 1";
    $resultado = $this->conexion->query($sql);

    $categorias = [];

    while ($fila = $resultado->fetch_assoc()) {
    $categoria = new Categoria(
    $fila["id_categoria"],
    $fila["nombre"],
    $fila["descripcion"],
    $fila["activo"]
    );

    $categorias[] = $categoria;
    }

    return $categorias;
    }
    }

    ?>

    Esto nos permitirá cargar categorías dinámicamente en el formulario de alta de productos.


    Fase 17: login usando UsuarioDAO

    Para el login crearemos la clase UsuarioDAO.

    Esta clase tendrá un método para buscar un usuario por su nombre de usuario o email.

    Ejemplo:

    public function obtenerPorUsuario($usuario) {
    $sql = "SELECT * FROM usuarios WHERE usuario = ? OR email = ?";
    $stmt = $this->conexion->prepare($sql);
    $stmt->bind_param("ss", $usuario, $usuario);
    $stmt->execute();

    $resultado = $stmt->get_result();

    if ($fila = $resultado->fetch_assoc()) {
    return new Usuario(
    $fila["id_usuario"],
    $fila["nombre"],
    $fila["email"],
    $fila["usuario"],
    $fila["password"],
    $fila["rol"]
    );
    }

    return null;
    }

    Después, en validar-login.php:

    session_start();

    require_once "clases/UsuarioDAO.php";

    $usuarioFormulario = $_POST["usuario"];
    $passwordFormulario = $_POST["password"];

    $usuarioDAO = new UsuarioDAO();
    $usuario = $usuarioDAO->obtenerPorUsuario($usuarioFormulario);

    if ($usuario != null && password_verify($passwordFormulario, $usuario->getPassword())) {
    $_SESSION["usuario"] = $usuario->getUsuario();
    $_SESSION["rol"] = $usuario->getRol();

    header("Location: admin/panel.php");
    exit();
    } else {
    header("Location: login.php?error=1");
    exit();
    }

    Así el login queda mucho más ordenado.


    Fase 18: protección de páginas privadas

    Seguiremos usando sesiones para proteger la parte administrativa.

    El archivo includes/seguridad.php puede mantenerse parecido a la versión anterior.

    <?php

    session_start();

    if (!isset($_SESSION["usuario"])) {
    header("Location: ../login.php");
    exit();
    }

    ?>

    En cada página privada incluiremos este archivo.

    <?php include("../includes/seguridad.php"); ?>

    Fase 19: subida de imágenes usando una función auxiliar

    La subida de imágenes puede hacerse al principio dentro de producto-guardar.php, pero podemos mejorarla creando una función o una clase auxiliar.

    Una opción sencilla sería crear:

    clases/GestorImagenes.php

    Ejemplo:

    <?php

    class GestorImagenes {

    public static function subirImagen($archivo, $carpetaDestino) {
    $nombreImagen = time() . "_" . basename($archivo["name"]);
    $rutaDestino = $carpetaDestino . $nombreImagen;

    if (move_uploaded_file($archivo["tmp_name"], $rutaDestino)) {
    return $nombreImagen;
    }

    return null;
    }
    }

    ?>

    Después, en producto-guardar.php:

    require_once "../clases/GestorImagenes.php";

    $imagen = GestorImagenes::subirImagen(
    $_FILES["imagen"],
    "../img/productos/"
    );

    $producto->setImagen($imagen);

    Esto permite separar la lógica de subida de archivos del resto del código.


    Fase 20: autoload básico de clases

    Cuando el proyecto crece, puede resultar pesado escribir muchos require_once.

    Por ejemplo:

    require_once "clases/Conexion.php";
    require_once "clases/Producto.php";
    require_once "clases/ProductoDAO.php";
    require_once "clases/Categoria.php";
    require_once "clases/CategoriaDAO.php";

    Para evitarlo, podemos crear un pequeño autoload.

    Ejemplo en includes/autoload.php:

    <?php

    spl_autoload_register(function ($nombreClase) {
    require_once __DIR__ . "/../clases/" . $nombreClase . ".php";
    });

    ?>

    Después, en cada página solo haríamos:

    require_once "includes/autoload.php";

    O desde la carpeta admin:

    require_once "../includes/autoload.php";

    Esto nos permitirá cargar clases automáticamente cuando las necesitemos.


    Fase 21: diagrama de clases

    En esta versión será especialmente importante trabajar con un diagrama de clases.

    El diagrama nos ayudará a entender qué clases existen y cómo se relacionan.

    Algunas clases principales serán:

    • Conexion
    • Producto
    • Categoria
    • Usuario
    • ProductoDAO
    • CategoriaDAO
    • UsuarioDAO
    • GestorImagenes

    La relación sería sencilla:

    • ProductoDAO usa Conexion.
    • ProductoDAO crea y devuelve objetos Producto.
    • CategoriaDAO usa Conexion.
    • CategoriaDAO crea y devuelve objetos Categoria.
    • UsuarioDAO usa Conexion.
    • UsuarioDAO crea y devuelve objetos Usuario.
    • Las páginas PHP usan los DAO para obtener o guardar datos.

    Este diagrama nos permitirá ver que las páginas ya no hablan directamente con la base de datos, sino que lo hacen a través de clases especializadas.


    Fase 22: diagrama de base de datos

    El diagrama de base de datos seguirá siendo parecido al de la versión anterior.

    Tendremos tablas como:

    • usuarios
    • categorias
    • productos
    • mensajes
    • pedidos
    • detalle_pedido
    • carrito
    • carrito_producto

    La tabla más importante al principio será productos, relacionada con categorias.

    La diferencia es que ahora intentaremos que las tablas tengan una correspondencia clara con las clases del proyecto.

    Por ejemplo:

    • Tabla productos → Clase Producto
    • Tabla categorias → Clase Categoria
    • Tabla usuarios → Clase Usuario

    Esto ayuda a entender la relación entre el modelo de datos y el modelo de objetos.


    Fase 23: preparación para hosting

    El despliegue en hosting será similar al de la versión anterior.

    Tendremos que subir:

    • Archivos PHP.
    • Carpeta clases/.
    • Carpeta includes/.
    • Carpeta css/.
    • Carpeta img/.
    • Base de datos exportada.

    También deberemos modificar los datos de conexión dentro de la clase Conexion.

    En local podríamos tener:

    private $servidor = "localhost";
    private $usuario = "root";
    private $password = "";
    private $baseDatos = "tienda_cuencos";

    En hosting tendremos otros datos:

    private $servidor = "servidor_del_hosting";
    private $usuario = "usuario_hosting";
    private $password = "password_hosting";
    private $baseDatos = "base_datos_hosting";

    Esta parte nos ayudará a entender que una aplicación debe adaptarse al entorno donde se ejecuta.


    Fase 24: ejecución en Docker

    También podremos preparar el proyecto para ejecutarlo en Docker.

    La diferencia principal será que la clase Conexion deberá conectarse al servicio de base de datos usando el nombre del contenedor.

    Por ejemplo, si en docker-compose.yml el servicio de base de datos se llama db, entonces en PHP usaremos:

    private $servidor = "db";

    Ejemplo de docker-compose.yml:

    services:
    web:
    image: php:8.2-apache
    ports:
    - "8080:80"
    volumes:
    - ./src:/var/www/html

    db:
    image: mariadb:10.11
    environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: tienda_cuencos
    MYSQL_USER: usuario
    MYSQL_PASSWORD: usuario

    phpmyadmin:
    image: phpmyadmin
    ports:
    - "8081:80"
    environment:
    PMA_HOST: db

    Con esta configuración podríamos acceder a la web desde:

    http://localhost:8080

    Y a phpMyAdmin desde:

    http://localhost:8081

    Fase 25: documentación final del proyecto

    Al terminar esta versión, cada alumno deberá documentar el proyecto.

    La documentación debería incluir:

    • Explicación general del proyecto.
    • Diferencias entre la versión básica y la versión POO.
    • Estructura de carpetas.
    • Diagrama de clases.
    • Diagrama de base de datos.
    • Explicación de las clases principales.
    • Explicación de las clases DAO.
    • Explicación del CRUD.
    • Capturas de pantalla.
    • Problemas encontrados.
    • Mejoras posibles.
    • Conclusión personal.

    En esta versión será especialmente importante que el alumno sepa explicar por qué se han creado ciertas clases y qué responsabilidad tiene cada una.


    26. Qué aprenderemos con esta versión

    Con esta versión aprenderemos a organizar mejor un proyecto PHP.

    No solo veremos cómo hacer que una aplicación funcione, sino cómo estructurarla para que sea más clara y mantenible.

    Aprenderemos conceptos como:

    • Clases.
    • Objetos.
    • Atributos.
    • Métodos.
    • Constructores.
    • Getters y setters.
    • Encapsulación.
    • DAO.
    • Separación de responsabilidades.
    • Consultas preparadas.
    • Sesiones.
    • Subida de archivos.
    • Reutilización de código.
    • Relación entre tablas y clases.
    • Preparación del proyecto para hosting o Docker.

    Esta versión es un paso intermedio muy importante antes de trabajar con arquitecturas más avanzadas como MVC o frameworks como Laravel.


    27. Conclusión

    La versión orientada a objetos de Sonido Interior nos permitirá mejorar el mismo proyecto que ya conocemos.

    En lugar de empezar una aplicación totalmente nueva, evolucionaremos una tienda sencilla construida con PHP básico hacia una estructura más ordenada y profesional.

    Esto nos permitirá entender mejor por qué existe la programación orientada a objetos y qué problemas resuelve.

    La idea principal es que el alumno vea una evolución clara:

    Primero hacemos que funcione.

    Después hacemos que esté mejor organizado.

    Y finalmente preparamos el proyecto para poder crecer, mantenerse y desplegarse en un entorno real.

  • Proyecto web en PHP: tienda de cuencos tibetanos

    Proyecto web en PHP: tienda de cuencos tibetanos

    En este proyecto vamos a desarrollar paso a paso una aplicación web completa utilizando HTML, CSS, PHP y MySQL. La temática elegida será una tienda online de cuencos tibetanos, llamada Sonido Interior.

    El objetivo no es solamente crear una web bonita, sino entender cómo se construye una aplicación web real desde cero: primero diseñaremos la parte visual, después organizaremos el código con PHP, más adelante conectaremos la aplicación con una base de datos y finalmente prepararemos el proyecto para poder ejecutarlo en un hosting o dentro de un contenedor.

    Este proyecto nos servirá para repasar y aprender conceptos fundamentales del desarrollo web backend con PHP.


    1. Objetivo general del proyecto

    Vamos a crear una tienda web sencilla donde se puedan consultar productos relacionados con cuencos tibetanos, meditación y sonoterapia.

    La aplicación tendrá dos partes principales:

    La primera será la parte pública, visible para cualquier visitante. En ella se podrá ver la página de inicio, consultar el catálogo de productos y acceder a información básica de la tienda.

    La segunda será la parte administrativa, pensada para el propietario o administrador de la tienda. Desde esta zona se podrán añadir productos, consultar el listado de productos existentes, editar información y borrar productos.

    Aunque al principio trabajaremos con páginas estáticas, poco a poco iremos añadiendo funcionalidad real mediante PHP y MySQL.


    2. Tecnologías que vamos a utilizar

    Durante el proyecto trabajaremos con varias tecnologías habituales en el desarrollo web.

    Usaremos HTML para crear la estructura de las páginas. Con HTML definiremos los títulos, formularios, menús, tablas, tarjetas de productos y el resto de elementos visibles.

    Usaremos CSS para dar estilo al proyecto. Definiremos colores, tamaños, márgenes, distribución de columnas, botones, tarjetas y diseño general de la web.

    Usaremos PHP para programar la parte del servidor. PHP nos permitirá reutilizar partes comunes de la web, procesar formularios, conectarnos a la base de datos, trabajar con sesiones y generar contenido dinámico.

    Usaremos MySQL o MariaDB como sistema de base de datos. Ahí guardaremos los productos, categorías, usuarios administradores, mensajes y otros datos necesarios.

    También utilizaremos un servidor local, como XAMPP, MAMP, Laragon, Docker o una máquina Linux con Apache, PHP y MySQL instalados.


    3. Resultado final esperado

    Al terminar el proyecto tendremos una aplicación web funcional con las siguientes partes:

    • Página de inicio.
    • Catálogo público de productos.
    • Página de login para administración.
    • Panel administrativo.
    • Formulario para añadir productos.
    • Listado administrativo de productos.
    • Edición de productos.
    • Borrado de productos.
    • Subida de una imagen por producto.
    • Base de datos relacional.
    • Código organizado mediante includes.
    • Posibilidad de instalar el proyecto en un hosting o contenedor.

    El resultado será una primera versión de una tienda online. No será todavía una tienda profesional completa con pagos reales, pero sí tendrá la estructura base de una aplicación web real.


    4. Fase 1: análisis de la idea

    Antes de empezar a programar, lo primero será entender qué queremos construir.

    Nuestra tienda se llamará Sonido Interior y venderá productos como:

    • Cuencos tibetanos pequeños.
    • Cuencos tibetanos medianos.
    • Cuencos tibetanos grandes.
    • Cuencos grabados.
    • Mazas.
    • Cojines.
    • Sets de meditación.
    • Accesorios relacionados con la sonoterapia.

    Esta fase es importante porque antes de escribir código debemos saber qué páginas necesita la web, qué datos manejará y qué funcionalidades tendrá.

    En clase analizaremos las necesidades básicas de la aplicación y pensaremos qué información debe tener cada producto.

    Por ejemplo, un producto podrá tener:

    • Nombre.
    • Descripción.
    • Precio.
    • Stock.
    • Categoría.
    • Imagen.
    • Diámetro.
    • Peso.
    • Material.
    • Nota musical.
    • Procedencia.
    • Estado activo o inactivo.

    5. Fase 2: diseño del prototipo visual

    Después de definir la idea, crearemos un prototipo visual de la aplicación.

    El prototipo nos servirá como referencia antes de programar. No empezaremos directamente escribiendo código sin saber cómo queremos que se vea la web.

    Diseñaremos varias pantallas principales:

    • Home o página de inicio.
    • Página de login.
    • Página de alta de productos.
    • Catálogo público.
    • Listado administrativo de productos.

    La home tendrá una estética tranquila y artesanal, con colores beige, dorados, marrones suaves y blanco roto. La intención es que el diseño encaje con la temática de bienestar, meditación y sonido.

    En esta fase podremos usar herramientas como Figma para replicar el diseño y entender la distribución visual antes de pasar a HTML y CSS.


    6. Fase 3: creación de la maqueta en HTML y CSS

    Una vez tengamos claro el diseño, empezaremos a crear las páginas en HTML y CSS.

    En esta fase todavía no usaremos base de datos. El objetivo será construir la estructura visual de la aplicación.

    Crearemos páginas como:

    • index.html
    • catalogo.html
    • login.html
    • admin-alta-producto.html
    • admin-listado-productos.html

    También crearemos una carpeta para los estilos:

    • css/estilos.css

    Y una carpeta para las imágenes:

    • img/

    Durante esta parte trabajaremos conceptos importantes de HTML y CSS:

    • Estructura básica de una página HTML.
    • Etiquetas semánticas.
    • Formularios.
    • Tablas.
    • Tarjetas de producto.
    • Menús de navegación.
    • Botones.
    • Imágenes.
    • Organización visual mediante CSS.
    • Diseño de una zona pública y una zona administrativa.

    Esta fase es fundamental porque nos permite construir la parte visual sin mezclarnos todavía con la lógica de programación.


    7. Fase 4: conversión del proyecto a PHP

    Cuando las páginas HTML estén preparadas, convertiremos el proyecto a PHP.

    Esto significa que cambiaremos archivos como:

    • index.html por index.php
    • catalogo.html por catalogo.php
    • login.html por login.php

    La ventaja de usar PHP es que podremos dividir la web en partes reutilizables.

    Por ejemplo, muchas páginas tendrán la misma cabecera, el mismo menú y el mismo pie de página. No tiene sentido copiar y pegar ese código en todos los archivos.

    Para solucionarlo, crearemos una carpeta llamada:

    • includes/

    Dentro colocaremos archivos comunes como:

    • header.php
    • menu.php
    • menu-admin.php
    • footer.php

    Después, desde cada página principal podremos incluir esos fragmentos de código usando PHP.

    Ejemplo:

    <?php include("includes/header.php"); ?>
    <?php include("includes/menu.php"); ?>
    
    <main>
        <h1>Bienvenido a Sonido Interior</h1>
        <p>Cuencos tibetanos artesanales para meditación y bienestar.</p>
    </main>
    
    <?php include("includes/footer.php"); ?>
    

    Con esto aprenderemos uno de los usos más importantes de PHP al inicio: reutilizar partes comunes de una web.


    8. Fase 5: organización de carpetas del proyecto

    El proyecto debe estar bien organizado desde el principio.

    Una posible estructura será la siguiente:

    sonido-interior/
    │
    ├── index.php
    ├── catalogo.php
    ├── login.php
    ├── admin-alta-producto.php
    ├── admin-listado-productos.php
    │
    ├── includes/
    │   ├── header.php
    │   ├── menu.php
    │   ├── menu-admin.php
    │   └── footer.php
    │
    ├── css/
    │   └── estilos.css
    │
    ├── img/
    │   └── productos/
    │
    └── sql/
        └── base_datos.sql
    

    Más adelante añadiremos nuevos archivos para guardar, editar, borrar y consultar productos.

    La organización es importante porque en un proyecto real no podemos tener todos los archivos mezclados sin ningún criterio.


    9. Fase 6: diseño de la base de datos

    Cuando ya tengamos la parte visual y la estructura básica en PHP, pasaremos a crear la base de datos.

    La base de datos será la encargada de almacenar la información real del proyecto.

    Crearemos una base de datos llamada, por ejemplo:

    tienda_cuencos
    

    Dentro de ella podremos tener varias tablas:

    • usuarios
    • categorias
    • productos
    • mensajes
    • pedidos
    • detalle_pedido
    • carrito
    • carrito_producto

    Para empezar, nos centraremos sobre todo en las tablas más importantes:

    • usuarios
    • categorias
    • productos

    La tabla usuarios almacenará los datos de los administradores.

    La tabla categorias guardará las categorías de productos.

    La tabla productos guardará la información de cada cuenco o accesorio.


    10. Fase 7: creación de la tabla de productos

    La tabla de productos será una de las más importantes del proyecto.

    Podría tener una estructura similar a esta:

    CREATE TABLE productos (
        id_producto INT AUTO_INCREMENT PRIMARY KEY,
        nombre VARCHAR(150) NOT NULL,
        descripcion TEXT,
        precio DECIMAL(10,2) NOT NULL,
        stock INT NOT NULL,
        imagen VARCHAR(255),
        diametro DECIMAL(5,2),
        peso DECIMAL(8,2),
        material VARCHAR(100),
        nota_musical VARCHAR(50),
        procedencia VARCHAR(100),
        activo BOOLEAN DEFAULT true,
        fecha_alta DATETIME DEFAULT CURRENT_TIMESTAMP,
        id_categoria INT,
        FOREIGN KEY (id_categoria) REFERENCES categorias(id_categoria)
    );
    

    Con esta tabla podremos guardar la información de cada producto y luego mostrarla en la parte pública y administrativa.


    11. Fase 8: conexión de PHP con MySQL

    Para que PHP pueda trabajar con la base de datos, necesitaremos crear un archivo de conexión.

    Este archivo se puede llamar:

    includes/conexion.php
    

    Dentro escribiremos los datos necesarios para conectarnos al servidor MySQL.

    Ejemplo inicial:

    <?php
    
    $servidor = "localhost";
    $usuario = "root";
    $password = "";
    $baseDatos = "tienda_cuencos";
    
    $conexion = new mysqli($servidor, $usuario, $password, $baseDatos);
    
    if ($conexion->connect_error) {
        die("Error de conexión: " . $conexion->connect_error);
    }
    
    $conexion->set_charset("utf8");
    
    ?>
    

    A partir de este momento, cualquier página que necesite consultar la base de datos podrá incluir este archivo.

    Ejemplo:

    <?php include("includes/conexion.php"); ?>
    

    12. Fase 9: mostrar productos desde la base de datos

    Cuando tengamos productos guardados en la base de datos, modificaremos el catálogo público.

    Al principio, los productos estarán escritos directamente en HTML. Después, haremos que PHP los lea desde MySQL.

    La página catalogo.php realizará una consulta parecida a esta:

    $sql = "SELECT * FROM productos WHERE activo = 1";
    $resultado = $conexion->query($sql);
    

    Después recorreremos los resultados y mostraremos cada producto en una tarjeta.

    Ejemplo básico:

    while ($producto = $resultado->fetch_assoc()) {
        echo "<article class='tarjeta-producto'>";
        echo "<img src='img/productos/" . $producto["imagen"] . "' alt='" . $producto["nombre"] . "'>";
        echo "<h3>" . $producto["nombre"] . "</h3>";
        echo "<p>" . $producto["precio"] . " €</p>";
        echo "</article>";
    }
    

    Con esto veremos una de las grandes ventajas de usar PHP: la página se genera automáticamente con los datos de la base de datos.


    13. Fase 10: formulario de alta de productos

    Después crearemos la página para añadir productos desde la zona administrativa.

    La página será:

    admin-alta-producto.php
    

    El formulario tendrá campos como:

    • Nombre.
    • Descripción.
    • Categoría.
    • Precio.
    • Stock.
    • Diámetro.
    • Peso.
    • Material.
    • Nota musical.
    • Procedencia.
    • Imagen.

    El formulario enviará los datos mediante el método POST.

    Ejemplo:

    <form action="producto-guardar.php" method="POST" enctype="multipart/form-data">
        <label>Nombre del producto</label>
        <input type="text" name="nombre">
    
        <label>Precio</label>
        <input type="number" step="0.01" name="precio">
    
        <label>Stock</label>
        <input type="number" name="stock">
    
        <label>Imagen del producto</label>
        <input type="file" name="imagen">
    
        <button type="submit">Guardar producto</button>
    </form>
    

    El atributo enctype="multipart/form-data" será necesario para poder subir imágenes.


    14. Fase 11: guardar productos en la base de datos

    El formulario de alta enviará los datos a un archivo llamado:

    producto-guardar.php
    

    Ese archivo recogerá los datos enviados por POST y realizará un INSERT en la base de datos.

    Ejemplo simplificado:

    $nombre = $_POST["nombre"];
    $descripcion = $_POST["descripcion"];
    $precio = $_POST["precio"];
    $stock = $_POST["stock"];
    
    $sql = "INSERT INTO productos (nombre, descripcion, precio, stock)
            VALUES ('$nombre', '$descripcion', '$precio', '$stock')";
    
    $conexion->query($sql);
    

    Más adelante mejoraremos este código usando validaciones y consultas preparadas para evitar problemas de seguridad.


    15. Fase 12: subida de imágenes

    Cada producto tendrá una imagen principal.

    Para subir imágenes trabajaremos con la variable especial de PHP:

    $_FILES
    

    Cuando el usuario seleccione una imagen en el formulario, PHP podrá recibirla y moverla a una carpeta del proyecto.

    La carpeta recomendada será:

    img/productos/
    

    El proceso será:

    1. El usuario selecciona una imagen.
    2. El formulario envía el archivo al servidor.
    3. PHP recibe el archivo temporal.
    4. PHP mueve el archivo a img/productos/.
    5. Se guarda el nombre del archivo en la base de datos.

    Ejemplo básico:

    $nombreImagen = $_FILES["imagen"]["name"];
    $rutaTemporal = $_FILES["imagen"]["tmp_name"];
    $rutaDestino = "img/productos/" . $nombreImagen;
    
    move_uploaded_file($rutaTemporal, $rutaDestino);
    

    Después guardaremos $nombreImagen en la tabla productos.


    16. Fase 13: listado administrativo de productos

    Además del catálogo público, crearemos una página administrativa donde se puedan ver todos los productos en formato tabla.

    La página será:

    admin-listado-productos.php
    

    Mostrará datos como:

    • ID.
    • Imagen.
    • Nombre.
    • Categoría.
    • Precio.
    • Stock.
    • Estado.
    • Acciones.

    Las acciones principales serán:

    • Editar.
    • Borrar.
    • Añadir nuevo producto.

    Ejemplo de enlaces:

    <a href="producto-editar.php?id=3">Editar</a>
    <a href="producto-borrar.php?id=3">Borrar</a>
    

    Estos enlaces enviarán el identificador del producto por la URL usando el método GET.


    17. Fase 14: edición de productos

    La edición permitirá modificar los datos de un producto ya existente.

    Crearemos una página llamada:

    producto-editar.php
    

    Esta página recibirá el ID del producto mediante la URL.

    Ejemplo:

    producto-editar.php?id=3
    

    Con ese ID, PHP consultará la base de datos, recuperará los datos actuales del producto y los mostrará dentro de un formulario.

    Después, el formulario enviará los datos modificados a:

    producto-actualizar.php
    

    Ese archivo realizará una consulta UPDATE.

    Ejemplo:

    UPDATE productos 
    SET nombre = 'Cuenco tibetano mediano',
        precio = 89.00,
        stock = 5
    WHERE id_producto = 3;
    

    18. Fase 15: borrado de productos

    También implementaremos la opción de borrar productos.

    Podemos hacerlo de dos formas.

    La primera forma es el borrado físico, que elimina el producto de la base de datos.

    DELETE FROM productos WHERE id_producto = 3;
    

    La segunda forma es el borrado lógico, que no elimina realmente el producto, sino que lo marca como inactivo.

    UPDATE productos SET activo = false WHERE id_producto = 3;
    

    En este proyecto es recomendable usar borrado lógico, porque es más parecido a lo que se hace en muchas aplicaciones reales. De esta forma, el producto deja de mostrarse en el catálogo, pero sus datos siguen guardados.


    19. Fase 16: login de administración

    La zona administrativa no debería estar abierta para cualquier usuario.

    Por eso crearemos un sistema de login.

    Tendremos una página:

    login.php
    

    Y una tabla de usuarios en la base de datos.

    El formulario de login pedirá:

    • Usuario o email.
    • Contraseña.

    Cuando el administrador introduzca sus datos, PHP comprobará si existe ese usuario y si la contraseña es correcta.

    Si todo está bien, se creará una sesión.

    Ejemplo:

    session_start();
    $_SESSION["usuario"] = $usuario;
    $_SESSION["rol"] = "admin";
    

    A partir de ese momento, el administrador podrá acceder a las páginas privadas.


    20. Fase 17: protección de páginas privadas

    No basta con tener una página de login. También debemos proteger las páginas administrativas.

    Para ello crearemos un archivo:

    includes/seguridad.php
    

    Este archivo comprobará si existe una sesión iniciada.

    Ejemplo:

    <?php
    
    session_start();
    
    if (!isset($_SESSION["usuario"])) {
        header("Location: login.php");
        exit();
    }
    
    ?>
    

    Después incluiremos este archivo al principio de cada página privada.

    Ejemplo:

    <?php include("includes/seguridad.php"); ?>
    

    Así evitaremos que alguien pueda entrar directamente escribiendo la URL de una página administrativa.


    21. Fase 18: cierre de sesión

    También necesitaremos una opción para cerrar sesión.

    Crearemos un archivo:

    logout.php
    

    Este archivo destruirá la sesión y devolverá al usuario a la página de login o a la home.

    Ejemplo:

    <?php
    
    session_start();
    session_destroy();
    
    header("Location: login.php");
    exit();
    
    ?>
    

    22. Fase 19: validaciones básicas

    Una vez que la aplicación funcione, empezaremos a mejorarla con validaciones.

    Validar significa comprobar que los datos que llegan al servidor tienen sentido.

    Por ejemplo:

    • Que el nombre del producto no esté vacío.
    • Que el precio sea mayor que cero.
    • Que el stock sea un número entero.
    • Que la imagen tenga una extensión permitida.
    • Que el usuario y la contraseña del login no estén vacíos.

    Las validaciones son importantes porque nunca debemos confiar ciegamente en los datos que llegan desde un formulario.


    23. Fase 20: mejora de seguridad con consultas preparadas

    Al principio podemos hacer consultas SQL sencillas para entender el funcionamiento.

    Pero después debemos mejorar la seguridad usando consultas preparadas.

    Las consultas preparadas ayudan a evitar ataques de inyección SQL.

    En lugar de meter directamente los datos dentro de la consulta, usamos parámetros.

    Ejemplo orientativo:

    $stmt = $conexion->prepare("INSERT INTO productos (nombre, precio, stock) VALUES (?, ?, ?)");
    $stmt->bind_param("sdi", $nombre, $precio, $stock);
    $stmt->execute();
    

    Esto es más seguro y más profesional que concatenar directamente los valores dentro de una cadena SQL.


    24. Fase 21: mejora de contraseñas

    Las contraseñas no deben guardarse nunca en texto plano.

    Para guardar contraseñas correctamente usaremos:

    password_hash()
    

    Y para comprobarlas:

    password_verify()
    

    Ejemplo para crear una contraseña cifrada:

    $passwordCifrada = password_hash($password, PASSWORD_DEFAULT);
    

    Ejemplo para comprobar una contraseña:

    if (password_verify($passwordIntroducida, $passwordGuardada)) {
        echo "Contraseña correcta";
    }
    

    Esta parte es fundamental para entender la seguridad básica de una aplicación web.


    25. Fase 22: preparación para hosting

    Cuando el proyecto funcione en local, veremos cómo prepararlo para subirlo a un hosting.

    Para ello tendremos que revisar varias cosas:

    • Que los archivos estén bien organizados.
    • Que la base de datos esté exportada en un archivo .sql.
    • Que el archivo de conexión tenga los datos correctos del hosting.
    • Que las rutas de imágenes funcionen correctamente.
    • Que las carpetas de subida tengan permisos adecuados.
    • Que no subamos archivos innecesarios.

    En un hosting real, los datos de conexión no suelen ser:

    localhost
    root
    sin contraseña
    

    Normalmente el proveedor nos dará:

    • Servidor de base de datos.
    • Nombre de la base de datos.
    • Usuario de base de datos.
    • Contraseña de base de datos.

    Tendremos que modificar el archivo conexion.php con esos datos.


    26. Fase 23: exportación e importación de la base de datos

    Para mover el proyecto desde nuestro equipo local a un hosting, tendremos que exportar la base de datos.

    Si usamos phpMyAdmin, el proceso será:

    1. Entrar en phpMyAdmin.
    2. Seleccionar la base de datos.
    3. Ir a la opción exportar.
    4. Guardar el archivo .sql.

    Después, en el hosting:

    1. Crear una nueva base de datos.
    2. Entrar en phpMyAdmin del hosting.
    3. Importar el archivo .sql.
    4. Revisar que las tablas y datos se han creado correctamente.

    Esta parte nos permitirá entender que una aplicación web no está formada solo por archivos PHP, sino también por una base de datos que debe acompañar al proyecto.


    27. Fase 24: despliegue en un contenedor Docker

    Además del hosting tradicional, también veremos la posibilidad de ejecutar el proyecto usando contenedores.

    Docker nos permite levantar un entorno completo con Apache, PHP y MySQL sin instalar todo manualmente en el sistema.

    Una estructura sencilla podría tener:

    • Un contenedor para Apache con PHP.
    • Un contenedor para MySQL o MariaDB.
    • Un contenedor opcional para phpMyAdmin.

    El proyecto podría tener un archivo:

    docker-compose.yml
    

    Con este archivo podríamos levantar todo el entorno usando un comando.

    Ejemplo orientativo:

    services:
      web:
        image: php:8.2-apache
        ports:
          - "8080:80"
        volumes:
          - ./src:/var/www/html
    
      db:
        image: mariadb:10.11
        environment:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: tienda_cuencos
          MYSQL_USER: usuario
          MYSQL_PASSWORD: usuario
    
      phpmyadmin:
        image: phpmyadmin
        ports:
          - "8081:80"
        environment:
          PMA_HOST: db
    

    Con esta opción podríamos acceder a la web desde:

    http://localhost:8080
    

    Y a phpMyAdmin desde:

    http://localhost:8081
    

    En este caso, el servidor de base de datos dentro de conexion.php no sería localhost, sino el nombre del servicio de Docker:

    $servidor = "db";
    

    Esto es muy importante, porque dentro de Docker los contenedores se comunican entre ellos usando el nombre del servicio.


    28. Fase 25: documentación final del proyecto

    Al terminar el proyecto, cada alumno deberá documentar el trabajo realizado.

    La documentación debería incluir:

    • Descripción del proyecto.
    • Tecnologías utilizadas.
    • Capturas de pantalla.
    • Estructura de carpetas.
    • Explicación de la base de datos.
    • Diagrama de base de datos.
    • Explicación de las páginas públicas.
    • Explicación de las páginas privadas.
    • Explicación del CRUD.
    • Problemas encontrados.
    • Mejoras posibles.
    • Conclusión personal.

    Documentar el proyecto es importante porque en el desarrollo real no basta con que algo funcione. También hay que saber explicar cómo se ha construido y por qué se ha hecho de esa manera.


    29. Posibles ampliaciones

    Cuando la versión básica esté terminada, podremos añadir mejoras.

    Algunas posibilidades son:

    • Buscador de productos.
    • Filtro por categoría.
    • Página de detalle de producto.
    • Carrito de compra.
    • Registro de clientes.
    • Gestión de pedidos.
    • Mensajes de contacto.
    • Panel con estadísticas.
    • Paginación de productos.
    • Validación avanzada de formularios.
    • Mejora de seguridad.
    • Diseño responsive para móviles.
    • Uso de variables de entorno.
    • Separación del código en funciones.
    • Primer acercamiento a arquitectura MVC.

    Estas ampliaciones nos permitirán convertir el proyecto en una aplicación cada vez más completa.


    30. Qué aprenderemos con este proyecto

    Este proyecto nos permitirá practicar muchos conceptos importantes.

    Aprenderemos a transformar una idea en una aplicación web. Veremos cómo pasar de un prototipo visual a páginas HTML y CSS, y después cómo convertir esas páginas en una aplicación dinámica con PHP.

    También aprenderemos a trabajar con formularios, recibir datos por POST, enviar datos por GET, consultar una base de datos, insertar registros, actualizar información y borrar datos.

    Además, veremos cómo proteger una zona privada con sesiones, cómo subir imágenes al servidor y cómo preparar el proyecto para ejecutarlo fuera del entorno local.

    El objetivo final es que cada alumno entienda el ciclo completo de desarrollo de una pequeña aplicación web: desde la idea inicial hasta su posible despliegue.


    31. Conclusión

    La tienda de cuencos tibetanos Sonido Interior será nuestro proyecto base para aprender desarrollo web con PHP.

    A lo largo de las clases iremos construyendo la aplicación paso a paso. Empezaremos por lo visual, seguiremos con la organización del código, añadiremos base de datos, implementaremos funcionalidades reales y terminaremos preparando el proyecto para su publicación.

    Este proyecto nos servirá como punto de partida para entender cómo funcionan muchas aplicaciones web reales.

    La clave será avanzar poco a poco, comprender cada fase y no limitarnos a copiar código. Cada parte del proyecto tendrá un objetivo concreto y nos ayudará a construir una base sólida para proyectos más avanzados.

  • Proyecto Mundo Oficios: diseño y desarrollo de una tienda online de muñecos por profesiones

    Proyecto Mundo Oficios: diseño y desarrollo de una tienda online de muñecos por profesiones

    Introducción

    En este proyecto vamos a diseñar, analizar y desarrollar una aplicación web completa basada en una tienda online ficticia llamada Mundo Oficios.

    La idea principal de la aplicación es crear una tienda de muñecos de estilo coleccionable, inspirados en diferentes profesiones: bomberos, doctoras, astronautas, chefs, policías, profesoras, constructores y muchas otras figuras similares.

    El objetivo no es únicamente crear una página bonita, sino recorrer varias fases reales del desarrollo de una aplicación web: desde la idea inicial y el diseño visual, hasta el análisis de clases, la base de datos, los casos de uso y la futura implementación en Java.

    Este proyecto nos servirá para practicar conceptos fundamentales del desarrollo de aplicaciones web, combinando diseño, programación, bases de datos y organización de un proyecto.


    1. Objetivo general del proyecto

    El objetivo de Mundo Oficios es construir una aplicación web que permita mostrar y gestionar productos de una tienda online.

    La aplicación tendrá dos partes principales:

    Parte pública

    Será la zona visible para cualquier usuario que visite la web. En esta parte se mostrarán los productos, las categorías, los packs, la información corporativa y las llamadas a la acción para consultar o comprar productos.

    La parte pública representa lo que vería un cliente normal al entrar en la tienda.

    Parte privada o panel de administración

    Será la zona interna de la aplicación. Solo podrán acceder usuarios autorizados, como administradores o gestores de la tienda.

    Desde esta zona privada se podrán dar de alta productos, modificar información, gestionar categorías, subir imágenes, controlar stock, revisar pedidos y consultar datos importantes de la tienda.


    2. Qué vamos a trabajar con este proyecto

    Este proyecto está pensado para trabajar varias competencias al mismo tiempo.

    Durante el desarrollo de Mundo Oficios vamos a practicar:

    • Diseño de interfaces con Figma.
    • Creación de prototipos de páginas web.
    • Organización visual de una web pública.
    • Diseño de una zona privada de administración.
    • Análisis de requisitos.
    • Diagrama de casos de uso.
    • Diagrama de clases.
    • Diagrama entidad-relación de base de datos.
    • Modelado de clases Java.
    • Diseño de tablas SQL.
    • Relación entre frontend, backend y base de datos.
    • Preparación de formularios web.
    • Gestión de productos.
    • Organización de imágenes, categorías y etiquetas.
    • Conceptos básicos de una tienda online.

    La intención es que el alumno no vea cada parte como algo aislado, sino como piezas de un mismo proyecto.

    Una aplicación real no se construye solo escribiendo código. Antes de programar hay que pensar qué necesita el usuario, cómo se va a organizar la información, qué pantallas va a tener la aplicación, qué datos se van a guardar y qué clases representarán esos datos dentro del programa.


    3. Descripción de la aplicación

    Mundo Oficios será una tienda online ficticia especializada en muñecos de diferentes profesiones.

    Cada producto representará una figura concreta. Por ejemplo:

    • Leo Bombero.
    • Nora Doctora.
    • Max Astronauta.
    • Sofía Chef.
    • Policía urbano.
    • Profesora de primaria.
    • Constructor.
    • Mecánica.
    • Científica.
    • Piloto.
    • Enfermero.

    Cada muñeco tendrá una ficha de producto con información básica:

    • Nombre del producto.
    • Profesión.
    • Categoría.
    • Precio.
    • Precio en oferta, si existe.
    • Stock disponible.
    • Edad recomendada.
    • Descripción corta.
    • Descripción completa.
    • Imágenes del producto.
    • Etiquetas.
    • Estado de publicación.
    • Indicación de si está visible o no en la tienda.

    La tienda estará organizada por categorías. Por ejemplo:

    • Emergencias.
    • Salud.
    • Educación.
    • Espacio.
    • Construcción.
    • Cocina.

    Esto nos permite trabajar una estructura típica de comercio electrónico, pero con una temática sencilla, visual y fácil de entender.


    4. Diseño de la página de inicio pública

    La primera parte del proyecto será el diseño de la home o página de inicio.

    La home es una de las páginas más importantes de una web, porque suele ser la primera pantalla que ve el usuario al entrar. Debe explicar de forma rápida qué ofrece la tienda, transmitir confianza y guiar al visitante hacia las secciones principales.

    En nuestro caso, la home de Mundo Oficios tendrá un diseño corporativo, limpio y moderno.

    Elementos principales de la home

    La página de inicio incluirá:

    Cabecera

    La cabecera contendrá el logotipo de Mundo Oficios, un menú de navegación y algunos iconos básicos.

    El menú puede incluir opciones como:

    • Inicio.
    • Profesiones.
    • Categorías.
    • Packs.
    • Sobre nosotros.
    • Contacto.

    También aparecerán iconos de búsqueda, usuario y carrito.

    La cabecera debe ser clara, sencilla y fácil de reconocer. En una web real, el usuario debe poder encontrar rápidamente las secciones importantes.

    Hero principal

    El hero es la sección principal que aparece al inicio de la página.

    En este proyecto, el hero tendrá una frase destacada como:

    Figuras articuladas que inspiran futuros

    Debajo se puede incluir un texto breve explicando la propuesta de la tienda:

    Descubre muñecos de profesiones diseñados para imaginar, jugar y aprender sin límites.

    También aparecerán botones de acción, por ejemplo:

    • Ver catálogo.
    • Conoce nuestra historia.

    El hero debe combinar texto, botones e imagen. En este caso, la imagen principal será un conjunto de muñecos representando varias profesiones.

    Sección Nuestra propuesta

    Esta sección explicará el valor de la marca.

    Puede incluir tres bloques:

    • Calidad que se siente.
    • Colecciona y combina.
    • Aprende jugando.

    Esta parte es importante porque no todo en una tienda online debe ser producto y precio. También hay que transmitir una idea de marca.

    Categorías

    La sección de categorías permitirá al usuario entrar en grupos de productos.

    Por ejemplo:

    • Emergencias.
    • Salud.
    • Espacio.
    • Construcción.

    Cada categoría puede representarse con una tarjeta sencilla, un icono y un enlace para acceder a ella.

    Productos destacados

    En lugar de mostrar muchos productos, la versión más corporativa de la home mostrará pocos productos destacados.

    Esto ayuda a que el diseño sea más limpio y elegante.

    Por ejemplo, podemos mostrar solo dos productos:

    • Leo Bombero.
    • Nora Doctora.

    Cada tarjeta de producto puede incluir:

    • Imagen.
    • Nombre.
    • Categoría.
    • Precio.
    • Valoración.
    • Botón de añadir al carrito.

    La home también puede incluir un banner para packs o colecciones.

    Por ejemplo:

    Packs y colecciones para cada aventura

    Esta sección puede servir para promocionar productos agrupados o descuentos especiales.

    Sección de confianza

    Una tienda online necesita transmitir seguridad.

    Por eso incluiremos una sección con elementos como:

    • Seguridad ante todo.
    • Diseño pensado para niños.
    • Envíos rápidos y seguros.
    • Atención cercana.

    Estos bloques ayudan a reforzar la confianza del usuario antes de comprar.

    Newsletter o llamada a la acción

    Al final de la página puede incluirse una sección para que el usuario deje su correo electrónico y reciba novedades u ofertas.

    Por ejemplo:

    Inspírate con novedades y ofertas exclusivas

    Esta parte nos permite practicar formularios simples dentro del diseño.

    El footer cerrará la página con enlaces secundarios, redes sociales, métodos de pago y datos básicos de la tienda.


    5. Diseño de la parte privada

    Además de la web pública, el proyecto tendrá una parte privada.

    La parte privada es el panel de administración de la tienda. No está pensada para clientes, sino para las personas que gestionan el contenido y los productos.

    En una aplicación real, este panel estaría protegido mediante usuario y contraseña.

    Página de login

    Antes de entrar al panel, el administrador deberá iniciar sesión.

    La pantalla de login tendrá un diseño corporativo y limpio, con dos zonas principales:

    Zona visual de marca

    En una parte de la pantalla aparecerá una imagen corporativa, con varios muñecos y un mensaje relacionado con la gestión de la tienda.

    Por ejemplo:

    Gestiona tu tienda de profesiones desde un solo lugar

    Esta zona ayuda a reforzar la identidad visual del proyecto.

    Formulario de acceso

    En la otra parte de la pantalla aparecerá el formulario de login.

    Tendrá los siguientes campos:

    • Correo electrónico.
    • Contraseña.
    • Checkbox de recordarme.
    • Enlace para recuperar contraseña.
    • Botón de iniciar sesión.
    • Opción secundaria de acceso con Google.
    • Texto de ayuda o soporte.

    Aunque en una primera fase no implementemos todas estas funcionalidades, sí es interesante diseñarlas para entender cómo sería una aplicación real.


    6. Alta de productos en la parte privada

    Una de las pantallas más importantes del panel privado será la de alta de producto.

    Esta pantalla permitirá al administrador crear una nueva ficha de producto para la tienda.

    Estructura general

    La pantalla tendrá:

    • Menú lateral.
    • Barra superior.
    • Zona principal de formulario.
    • Paneles auxiliares a la derecha.

    El menú lateral permitirá acceder a las diferentes secciones del panel.

    Puede incluir opciones como:

    • Resumen.
    • Productos.
    • Categorías.
    • Pedidos.
    • Clientes.
    • Promociones.
    • Estadísticas.
    • Ajustes.

    La opción Productos aparecerá destacada, porque estaremos dentro de esa sección.

    Barra superior

    La barra superior puede incluir:

    • Campo de búsqueda.
    • Icono de notificaciones.
    • Perfil del administrador.

    Estos elementos son habituales en paneles de administración modernos.

    Formulario de alta

    La parte central de la pantalla contendrá el formulario para crear un producto.

    Los campos principales serán:

    • Nombre del producto.
    • SKU.
    • Precio.
    • Precio oferta.
    • Categoría.
    • Profesión.
    • Stock.
    • Edad recomendada.
    • Descripción corta.
    • Descripción completa.
    • Etiquetas.
    • Producto destacado.
    • Visible en tienda.
    • Estado del producto.

    Este formulario nos permitirá trabajar muchos tipos de controles:

    • Inputs de texto.
    • Inputs numéricos.
    • Selectores desplegables.
    • Textareas.
    • Switches.
    • Radios.
    • Botones.
    • Zona de subida de imágenes.

    Galería de imágenes

    Cada producto podrá tener varias imágenes.

    Por ejemplo:

    • Imagen frontal.
    • Imagen lateral.
    • Imagen trasera.
    • Imagen de detalle.

    En el diseño aparecerá una sección de galería donde se podrán subir imágenes del producto.

    En una aplicación real, estas imágenes se guardarían en el servidor o en un servicio de almacenamiento, y en la base de datos se guardaría la ruta o URL de cada imagen.

    Panel de vista previa

    A la derecha del formulario puede aparecer una vista previa del producto.

    Esta vista previa permite comprobar cómo se verá el producto antes de publicarlo.

    Puede mostrar:

    • Imagen principal.
    • Nombre.
    • Categoría.
    • Precio.
    • Precio de oferta.
    • Stock.
    • SKU.

    Este tipo de panel ayuda mucho en aplicaciones de administración, porque permite validar la información antes de guardarla.

    Panel de organización

    También puede haber un bloque para información interna:

    • Colección.
    • Proveedor.
    • Clase de envío.
    • Notas internas.

    Esto no siempre será visible para el cliente, pero sí puede ser útil para la gestión interna de la tienda.

    Botones finales

    Al final del formulario tendremos dos acciones principales:

    • Guardar borrador.
    • Publicar producto.

    Esto nos permite explicar la diferencia entre un producto que está guardado pero no publicado y un producto que ya aparece en la tienda pública.


    7. Diagrama de casos de uso

    El diagrama de casos de uso nos ayuda a entender qué puede hacer cada tipo de usuario dentro del sistema.

    En este proyecto tenemos varios actores:

    Visitante

    Es una persona que entra en la web sin estar registrada.

    Puede:

    • Ver la página de inicio.
    • Ver el catálogo.
    • Filtrar productos.
    • Ver fichas de producto.
    • Registrarse o iniciar sesión.

    Cliente

    Es un usuario que puede comprar o consultar sus pedidos.

    Puede:

    • Ver productos.
    • Añadir productos al carrito.
    • Realizar pedidos.
    • Pagar pedidos.
    • Consultar sus pedidos.

    Administrador o gestor

    Es el usuario que accede a la parte privada.

    Puede:

    • Acceder al panel privado.
    • Gestionar productos.
    • Dar de alta productos.
    • Editar productos.
    • Eliminar o desactivar productos.
    • Subir imágenes.
    • Gestionar categorías.
    • Gestionar profesiones.
    • Gestionar pedidos.
    • Gestionar promociones.
    • Consultar estadísticas.
    • Gestionar usuarios.

    Pasarela de pago

    Es un sistema externo que interviene cuando el cliente paga un pedido.

    En una aplicación real, podría ser PayPal, Stripe, Redsys u otra plataforma similar.

    El diagrama de casos de uso nos sirve para ver el sistema desde el punto de vista funcional. No se centra en las clases ni en la base de datos, sino en las acciones que los usuarios pueden realizar.


    8. Diagrama de clases

    El diagrama de clases representa la estructura del sistema desde el punto de vista de la programación orientada a objetos.

    En Java, cada clase representará un concepto importante del proyecto.

    Clase Producto

    La clase Producto es una de las más importantes.

    Representa cada muñeco que se vende en la tienda.

    Puede tener atributos como:

    • id.
    • nombre.
    • sku.
    • precio.
    • precioOferta.
    • stock.
    • descripcionCorta.
    • descripcionCompleta.
    • edadRecomendada.
    • destacado.
    • visible.
    • estado.

    También puede tener métodos como:

    • publicar.
    • guardarBorrador.
    • aplicarOferta.
    • quitarOferta.
    • actualizarStock.
    • estaDisponible.

    Esta clase estará relacionada con otras clases como Categoria, Profesion, ImagenProducto, Etiqueta, Coleccion y Proveedor.

    Clase Categoria

    La clase Categoria sirve para agrupar productos.

    Por ejemplo:

    • Emergencias.
    • Salud.
    • Educación.
    • Espacio.
    • Construcción.
    • Cocina.

    Una categoría puede tener muchos productos.

    Clase Profesion

    La clase Profesion representa la profesión concreta del muñeco.

    Por ejemplo:

    • Bombero.
    • Doctora.
    • Astronauta.
    • Chef.
    • Policía.
    • Profesora.

    Es importante diferenciar categoría y profesión.

    Por ejemplo, un producto puede estar en la categoría Emergencias y tener la profesión Bombero.

    Clase ImagenProducto

    Un producto puede tener varias imágenes.

    Por eso existe la clase ImagenProducto.

    Esta clase puede guardar:

    • URL de la imagen.
    • Texto alternativo.
    • Si es imagen principal.
    • Orden de aparición.

    Esto permite que un mismo producto tenga una galería de imágenes.

    Clase Etiqueta

    Las etiquetas permiten clasificar productos de forma más flexible.

    Por ejemplo:

    • bombero.
    • emergencias.
    • regalo.
    • colección.
    • oferta.
    • niños.

    Un producto puede tener muchas etiquetas y una etiqueta puede estar asociada a muchos productos.

    Por eso esta relación suele convertirse en una tabla intermedia en la base de datos.

    Clase Cliente

    La clase Cliente representa a una persona que compra en la tienda.

    Puede tener:

    • nombre.
    • apellidos.
    • email.
    • teléfono.

    Un cliente puede tener varias direcciones y varios pedidos.

    Clase Pedido

    La clase Pedido representa una compra realizada por un cliente.

    Puede tener:

    • fecha.
    • estado.
    • subtotal.
    • gastos de envío.
    • total.

    Un pedido estará formado por varias líneas de pedido.

    Clase LineaPedido

    La clase LineaPedido representa cada producto concreto dentro de un pedido.

    Por ejemplo, si un cliente compra dos muñecos de bombero y uno de astronauta, el pedido tendrá dos líneas:

    • Línea 1: Leo Bombero, cantidad 2.
    • Línea 2: Max Astronauta, cantidad 1.

    Cada línea tiene su cantidad, precio unitario y subtotal.

    Clase Pago

    La clase Pago representa la información relacionada con el pago del pedido.

    Puede tener:

    • método de pago.
    • estado del pago.
    • importe.
    • fecha de pago.

    Clase Usuario

    La clase Usuario representa a quien accede al sistema.

    Puede tener distintos roles:

    • ADMIN.
    • GESTOR.
    • CLIENTE.

    En la parte privada nos interesan especialmente los usuarios administradores y gestores.


    9. Diagrama de base de datos

    El diagrama de base de datos representa cómo se guardará la información en tablas.

    Aunque el diagrama de clases y el diagrama de base de datos están relacionados, no son exactamente lo mismo.

    El diagrama de clases representa la estructura del programa en Java.

    El diagrama de base de datos representa cómo se almacenan los datos en MySQL, MariaDB u otro sistema similar.

    Tabla productos

    La tabla principal será productos.

    Contendrá campos como:

    • id_producto.
    • id_categoria.
    • id_profesion.
    • id_coleccion.
    • id_proveedor.
    • id_clase_envio.
    • nombre.
    • sku.
    • precio.
    • precio_oferta.
    • stock.
    • edad_recomendada.
    • descripcion_corta.
    • descripcion_completa.
    • destacado.
    • visible.
    • estado.
    • fecha_creacion.

    Esta tabla tendrá varias claves foráneas para relacionarse con otras tablas.

    Tabla categorias

    La tabla categorias guardará las categorías comerciales de la tienda.

    Campos principales:

    • id_categoria.
    • nombre.
    • descripcion.
    • icono.
    • activa.

    Tabla profesiones

    La tabla profesiones guardará las profesiones disponibles.

    Campos principales:

    • id_profesion.
    • nombre.
    • descripcion.
    • icono.

    Tabla imagenes_producto

    La tabla imagenes_producto guardará las imágenes asociadas a cada producto.

    Campos principales:

    • id_imagen.
    • id_producto.
    • url.
    • texto_alternativo.
    • principal.
    • orden.

    Esta tabla tiene una relación de uno a muchos con productos: un producto puede tener muchas imágenes.

    Tabla etiquetas

    La tabla etiquetas guardará etiquetas reutilizables.

    Como la relación entre productos y etiquetas es de muchos a muchos, necesitaremos una tabla intermedia llamada producto_etiqueta.

    Tabla clientes

    La tabla clientes guardará la información de los compradores.

    Campos principales:

    • id_cliente.
    • nombre.
    • apellidos.
    • email.
    • teléfono.
    • fecha_alta.

    Tabla direcciones

    La tabla direcciones permitirá guardar una o varias direcciones por cliente.

    Campos principales:

    • id_direccion.
    • id_cliente.
    • calle.
    • ciudad.
    • provincia.
    • codigo_postal.
    • país.

    Tabla pedidos

    La tabla pedidos guardará la información general de cada pedido.

    Campos principales:

    • id_pedido.
    • id_cliente.
    • id_direccion.
    • fecha.
    • estado.
    • subtotal.
    • gastos_envio.
    • total.

    Tabla lineas_pedido

    La tabla lineas_pedido guardará los productos incluidos en cada pedido.

    Campos principales:

    • id_linea.
    • id_pedido.
    • id_producto.
    • cantidad.
    • precio_unitario.
    • subtotal.

    Tabla pagos

    La tabla pagos guardará la información de pago del pedido.

    Campos principales:

    • id_pago.
    • id_pedido.
    • metodo.
    • estado.
    • importe.
    • fecha_pago.

    Tabla promociones

    La tabla promociones permitirá gestionar códigos de descuento o promociones.

    Campos principales:

    • id_promocion.
    • nombre.
    • codigo.
    • descuento.
    • fecha_inicio.
    • fecha_fin.
    • activa.

    Como una promoción puede aplicarse a varios productos, y un producto puede tener varias promociones, usaremos una tabla intermedia llamada producto_promocion.


    10. Fases del proyecto

    Para que el trabajo sea más ordenado, dividiremos el proyecto en varias fases.

    Fase 1: Comprensión del proyecto

    En esta fase analizaremos qué queremos construir.

    Responderemos preguntas como:

    • ¿Qué es Mundo Oficios?
    • ¿Qué usuarios tendrá?
    • ¿Qué productos se venderán?
    • ¿Qué partes tendrá la web?
    • ¿Qué necesita el administrador?
    • ¿Qué necesita el cliente?

    El objetivo de esta fase es entender el problema antes de diseñar o programar.

    Fase 2: Diseño visual en Figma

    En esta fase usaremos Figma para diseñar las pantallas principales.

    Trabajaremos:

    • Home pública.
    • Login de la parte privada.
    • Pantalla de alta de producto.
    • Elementos reutilizables.
    • Botones.
    • Tarjetas.
    • Formularios.
    • Menús.
    • Espaciados.
    • Colores.
    • Tipografía.

    El objetivo es que los alumnos entiendan que antes de programar una pantalla conviene diseñarla.

    Figma nos permite pensar la experiencia del usuario sin preocuparnos todavía por el código.

    Fase 3: Casos de uso

    En esta fase identificaremos qué puede hacer cada actor dentro del sistema.

    Trabajaremos con el diagrama de casos de uso para representar:

    • Visitante.
    • Cliente.
    • Administrador.
    • Pasarela de pago.

    El objetivo es comprender las funcionalidades principales de la aplicación.

    Fase 4: Diagrama de clases

    En esta fase pasaremos del análisis funcional a la estructura orientada a objetos.

    Diseñaremos las clases Java que representarán el sistema:

    • Producto.
    • Categoría.
    • Profesión.
    • ImagenProducto.
    • Cliente.
    • Pedido.
    • LíneaPedido.
    • Pago.
    • Usuario.

    El objetivo es entender cómo se transforma una idea de negocio en clases, atributos, métodos y relaciones.

    Fase 5: Diseño de base de datos

    En esta fase diseñaremos las tablas necesarias para almacenar la información.

    Trabajaremos con:

    • Claves primarias.
    • Claves foráneas.
    • Relaciones uno a muchos.
    • Relaciones muchos a muchos.
    • Tablas intermedias.
    • Tipos de datos.
    • Normalización básica.

    El objetivo es que los alumnos comprendan que la base de datos debe reflejar correctamente la estructura de la aplicación.

    Fase 6: Implementación de clases Java

    Una vez diseñado el modelo, podremos empezar a programar las clases Java.

    Por ejemplo:

    • Producto.java.
    • Categoria.java.
    • Profesion.java.
    • Cliente.java.
    • Pedido.java.
    • LineaPedido.java.

    Al principio pueden ser clases sencillas con atributos, constructores, getters, setters y algunos métodos básicos.

    Después podremos avanzar hacia una estructura más completa.

    Fase 7: Formularios web

    En esta fase empezaremos a transformar el diseño en páginas reales.

    Trabajaremos formularios como:

    • Login.
    • Alta de producto.
    • Registro de cliente.
    • Edición de producto.

    El formulario de alta de producto será especialmente importante, porque conectará con la lógica de productos de la aplicación.

    Fase 8: Conexión con base de datos

    En esta fase conectaremos la aplicación Java con la base de datos.

    Dependiendo del nivel del grupo, podremos hacerlo con:

    • JDBC.
    • DAO.
    • Servlets.
    • HTML o plantillas.
    • Frameworks más avanzados si procede.

    El objetivo será guardar, consultar, modificar y eliminar productos desde la base de datos.

    Fase 9: Panel privado funcional

    En esta fase construiremos la parte privada.

    El administrador podrá:

    • Iniciar sesión.
    • Ver productos.
    • Crear productos.
    • Editar productos.
    • Desactivar productos.
    • Subir o asignar imágenes.
    • Gestionar categorías.
    • Ver pedidos.

    No es necesario hacer todo perfecto desde el principio. Lo importante es avanzar por versiones.

    Fase 10: Revisión, pruebas y mejoras

    En la última fase revisaremos el proyecto.

    Comprobaremos:

    • Que las pantallas funcionan.
    • Que los formularios envían datos correctamente.
    • Que se validan los campos importantes.
    • Que la base de datos guarda la información.
    • Que las relaciones están bien planteadas.
    • Que el código está organizado.
    • Que el diseño es coherente.

    También podremos plantear mejoras futuras.


    11. Versión mínima del proyecto

    Como el proyecto puede crecer mucho, conviene definir una versión mínima.

    La versión mínima debería permitir:

    • Ver una home pública.
    • Ver un catálogo básico.
    • Entrar al panel privado.
    • Dar de alta productos.
    • Listar productos.
    • Editar productos.
    • Desactivar productos.
    • Guardar productos en base de datos.

    Con eso ya tendríamos una aplicación bastante completa para trabajar conceptos esenciales.

    No hace falta implementar desde el primer momento pagos reales, estadísticas avanzadas o gestión completa de clientes.


    12. Versión ampliada del proyecto

    Una vez terminada la versión mínima, se pueden añadir mejoras.

    Por ejemplo:

    • Carrito de compra.
    • Registro de clientes.
    • Gestión de pedidos.
    • Subida real de imágenes.
    • Buscador de productos.
    • Filtros por categoría.
    • Filtros por profesión.
    • Promociones y códigos de descuento.
    • Productos destacados.
    • Gestión de stock.
    • Panel de estadísticas.
    • Control de roles.
    • Validaciones avanzadas.
    • Diseño responsive.
    • API REST.
    • Integración con pasarela de pago simulada.

    Estas mejoras nos permitirían convertir el proyecto en una aplicación mucho más completa.


    13. Relación entre diseño, Java y base de datos

    Uno de los puntos más importantes de este proyecto es entender cómo se conectan las diferentes partes.

    Por ejemplo, en el diseño de Figma tenemos un formulario con el campo:

    Nombre del producto

    En Java ese dato puede corresponder al atributo:

    nombre

    Dentro de la clase:

    Producto

    Y en la base de datos se guardará en la columna:

    nombre

    Dentro de la tabla:

    productos

    Este mismo razonamiento se repite con otros campos:

    • Precio.
    • Stock.
    • Categoría.
    • Profesión.
    • Descripción.
    • Estado.
    • Visible.
    • Destacado.

    Así los alumnos pueden ver que el diseño no está separado del código. Lo que se dibuja en Figma después se convierte en HTML, formularios, clases Java y columnas de base de datos.


    14. Ejemplo de flujo: alta de producto

    Vamos a pensar en un ejemplo concreto.

    Un administrador quiere dar de alta un nuevo producto llamado Leo Bombero.

    Paso 1: Accede al panel privado

    El administrador entra en la pantalla de login e introduce su correo y contraseña.

    Si los datos son correctos, accede al panel.

    Paso 2: Entra en productos

    Dentro del menú lateral, pulsa en la opción Productos.

    Desde ahí selecciona la opción para crear un nuevo producto.

    Paso 3: Rellena el formulario

    Introduce los datos:

    • Nombre: Leo Bombero.
    • SKU: BOM-001.
    • Precio: 12,95 €.
    • Precio oferta: 9,95 €.
    • Categoría: Emergencias.
    • Profesión: Bombero.
    • Stock: 50.
    • Edad recomendada: 3+ años.
    • Descripción corta.
    • Descripción completa.
    • Etiquetas.
    • Imágenes.

    Paso 4: Guarda o publica

    El administrador puede guardar el producto como borrador o publicarlo directamente.

    Si lo publica, el producto pasará a estar visible en la tienda pública.

    Paso 5: El cliente lo ve en la tienda

    Un visitante o cliente entra en la web, ve el catálogo, filtra por emergencias y encuentra el producto Leo Bombero.

    Este ejemplo nos ayuda a conectar varias partes del proyecto:

    • Login.
    • Panel privado.
    • Formulario.
    • Producto.
    • Base de datos.
    • Catálogo público.

    15. Organización recomendada para el proyecto Java

    Cuando pasemos a Java, podemos organizar el proyecto por paquetes.

    Una estructura sencilla podría ser:

    src/
    ├── modelo/
    │ ├── Producto.java
    │ ├── Categoria.java
    │ ├── Profesion.java
    │ ├── ImagenProducto.java
    │ ├── Cliente.java
    │ ├── Pedido.java
    │ └── LineaPedido.java

    ├── dao/
    │ ├── ProductoDAO.java
    │ ├── CategoriaDAO.java
    │ └── ClienteDAO.java

    ├── controlador/
    │ ├── ProductoServlet.java
    │ ├── LoginServlet.java
    │ └── PedidoServlet.java

    ├── util/
    │ └── ConexionBD.java

    └── vista/
    ├── index.html
    ├── login.html
    ├── alta-producto.html
    └── listado-productos.html

    Esta organización separa responsabilidades:

    modelo contiene las clases principales.

    dao contiene las clases que trabajan con la base de datos.

    controlador contiene los servlets o controladores.

    util contiene clases auxiliares, como la conexión a base de datos.

    vista contiene las páginas HTML o plantillas.


    16. Posibles ampliaciones

    Los alumnos que avancen más rápido pueden añadir funcionalidades extra.

    Algunas ideas son:

    Buscador de productos

    Permitir buscar productos por nombre, profesión o categoría.

    Filtros avanzados

    Filtrar por:

    • Precio.
    • Categoría.
    • Profesión.
    • Edad recomendada.
    • Disponibilidad.
    • Producto destacado.

    Subida real de imágenes

    Permitir subir imágenes desde el formulario y guardarlas en el servidor.

    Control de roles

    Diferenciar permisos entre administrador y gestor.

    Por ejemplo:

    • El administrador puede gestionar usuarios.
    • El gestor solo puede gestionar productos y pedidos.

    Panel de estadísticas

    Mostrar datos como:

    • Número de productos.
    • Productos con poco stock.
    • Pedidos pendientes.
    • Ventas del mes.
    • Categorías más vendidas.

    Carrito completo

    Implementar un carrito con:

    • Añadir producto.
    • Modificar cantidad.
    • Eliminar producto.
    • Calcular total.
    • Confirmar pedido.

    API REST

    Crear una API para que el frontend pueda consultar productos desde Java.


    17. Qué aprenderemos realmente con este proyecto

    Aunque el proyecto se presenta como una tienda de muñecos, en realidad estamos trabajando conceptos aplicables a muchas aplicaciones web.

    Lo que aprendamos aquí se puede aplicar después a:

    • Una tienda de ropa.
    • Una tienda de videojuegos.
    • Una biblioteca.
    • Un sistema de reservas.
    • Una plataforma de cursos.
    • Un inventario de material.
    • Un sistema de gestión de alumnos.
    • Una aplicación de pedidos.

    La temática de los muñecos nos ayuda a que el proyecto sea visual y fácil de entender, pero la estructura técnica es la de una aplicación web real.


    18. Consejos

    Antes de empezar a programar, es importante entender bien el proyecto.

    No hay que lanzarse directamente al código sin pensar.

    Un buen desarrollo suele seguir este orden:

    Primero entendemos qué queremos construir.

    Después diseñamos las pantallas.

    Luego analizamos los casos de uso.

    Después pensamos las clases.

    Luego diseñamos la base de datos.

    Finalmente empezamos a programar.

    Si seguimos este proceso, el proyecto será más ordenado y será más fácil detectar errores.

    También es importante no intentar hacerlo todo de golpe. Una aplicación grande se construye por partes.

    Primero hacemos una versión sencilla que funcione. Después vamos añadiendo mejoras.


    19. Conclusión

    El proyecto Mundo Oficios nos permitirá trabajar un caso completo de desarrollo de aplicación web.

    Partiremos de una idea sencilla: una tienda online de muñecos por profesiones.

    A partir de esa idea iremos construyendo todo lo necesario:

    • Diseño visual de la web.
    • Prototipo en Figma.
    • Home pública.
    • Login privado.
    • Panel de administración.
    • Alta de productos.
    • Diagrama de casos de uso.
    • Diagrama de clases.
    • Diagrama de base de datos.
    • Clases Java.
    • Formularios.
    • Conexión con base de datos.
    • Gestión de productos.

    El objetivo final no es solo tener una aplicación funcionando, sino comprender el proceso completo que hay detrás de un proyecto web.

    Este proyecto nos va a permitir unir diseño, análisis y programación en un mismo trabajo, acercándonos a la forma en la que se desarrollan aplicaciones reales.


    Descargas