bookmark_borderSingle SignOn con Google en Spring Boot

  • Registrate en la consola de Google (API Console) https://console.developers.google.com/apis
  • Elige la opción de Credencials en el menu del lado izquierdo.
  • Crea un nuevo proyecto, o selecciona el proyecto donde deseas colocar el api key.
  • Incluye las referencias en el proyecto
    • org.springframework.security.oauth
    • org.springframework.cloud
  • En la configuración de seguridad, deshabilita el csrf. Se va a configurar ingresa la linea .oaut2Client(), el resto es para seguridad
	@Override
	protected void configure(HttpSecurity http) throws Exception {
        http
        .oauth2Client().and()
        .authorizeRequests()
            .antMatchers("/", "/api/ingredients").permitAll()
            .antMatchers("/profile", "/recipes/create").authenticated()
            .and()
        .formLogin()
            .defaultSuccessUrl("/")
            .usernameParameter("username")
            .passwordParameter("password")
            .loginPage("/login")
            .permitAll()
            .and()
        .logout()
        	.logoutUrl("/logout")
        	.logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
            .logoutSuccessUrl("/")
            .permitAll()
            .and()
        .csrf()
            .disable()
        .exceptionHandling()
            .accessDeniedPage("/403");
	}
	

bookmark_borderCrear usuario y darle permisos en mariadb

Los pasos para crear un nuevo usuario en mariadb. Es necesario que tengas el root o algun usuario con permisos de administración.

Ingresa a mariadb, si estas en el servidor puedes hacerlo con la siguiente sentencia, existen otras sentencias pero basicamente debes de iniciar sesión con el administrador.

$ sudo mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 682924
Server version: 10.3.29-MariaDB-0ubuntu0.20.10.1-log Ubuntu 20.10

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Crea el usuario con la siguiente sentencia:

MariaDB [(none)]> CREATE USER 'usuario'@localhost IDENTIFIED BY 'passwordusuario';

Donde:

  • usuario@localhost. Es el nombre del usuario y el lugar desde donde se puede conectar ese usuario. En este caso este usuario solo se puede conectar estando en el servidor registrado. Si quisieramos que este usuario se pudiera conectar desde otros equipos podriamos poner una IP fija o el % para indicar que se puede conectar desde cualquier equipo.
  • passwordusuario. Es la contraseña que va a utilizar el usuario para conectarse el servidor. Esta sentencia solo crea el usuario y no puede utilizar ningun recurso (base de datos, ejecución de procedimientos, etc) del servidor.

Despues de crear el usuario debe de otorgar los permisos al usuario con la siguiente sentencia.

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'usuario'@localhost IDENTIFIED BY 'passwordusuario';

Si solo deseamos dar permisos sobre una base de datos.

MariaDB [(none)]> GRANT ALL PRIVILEGES ON 'yourDB'.* TO 'usuario'@localhost;
MariaDB [(none)]> 

Bueno ahora llega el momento de revisar que todo funcione.

MariaDB [(none)]>  FLUSH PRIVILEGES;
MariaDB [(none)]>  SELECT host, user FROM mysql.user;
MariaDB [(none)]>  SHOW GRANTS FOR 'usuario'@localhost;

Si necesitas mas información acerca de CREATE USER o de GRANT PRIVILEGES ON TO.

bookmark_borderAnotaciones de JUnit

@BeforeEach. Se ejecuta el método antes de realizar cada uno de los test que se encuentra en la clase.

@AfterEach. Se ejecuta el método después de ejecutar cada uno de los métodos que se encuentra en la clase.

@BeforeAll. Se ejecuta el método antes de realizar cualquier método de las clases. (Solo se ejecuta una sola vez) es por eso que debe de un método estático.

@AfterAll. Se ejecuta el método después de realizar todas las pruebas de las clases. Solo se ejecuta una sola vez, es por eso que debe de ser un método estático. Utilice esto para liberar los recursos que están siendo atrapados, como bases de datos o archivos

@Test. Le indica al motor de JUnit que la función contiene un test.

@DisplayName. Cambia el nombre del test, sirve para darme una semántica mejor. En caso de no indicarse se el nombre que se muestra es el nombre de la función.

@Nestable. Sirve para indicar que la subclase también pertenece a la lista de pruebas unitarias de la clase principal. Solo puede ponerse en una subclase. Utilizar para generar una jerarquia

@RepeatedTest(). Sirve para hacer un test unitario que debe de ejecutarse en varias ocasiones
value, Indica el numero de repeticiones que se debe de ejecutar el test, ocupa algunas valores {index} y {argumentsWithNames}
name, Nombre que va a mostrarse en el

Parametros en la funcion 
    RepetitionInfo. Se inyecta por 

Assumption. Sirve para crer condicionales de como debe de ejecutarse.

@ParameterizedTest. sirve para pasar los valores a un test. Debe de estar seguido de la anotación que indique el Source, por ejemplo, en el @ValueSource
name. Cambia el texto que se pueda tener
@ValueSource(strings = {“100”, “200”})
void test(String arg) {

@CsvSource({“1,100”, “2,200”, “3,300”}). Cada entrada es una cadena separada por comas.
void testCsvSource(String indice, String monto) {
….

@CsvFileSource(resources = “/data.csv”).
Resource indica donde esta el archivo dentro de la carpeta de resources.

void testCsvFileSource(String monto). El método debe de tener tantos argumentos como columnas tenga el csv.

private static List methdo () {
….

@MethodSource(“nombreMethodo”). Debe de mostrase el nombre del método, que se va a inyectar, y debe de volver una Lista con el tipo de objeto el método debe de ser estático.
void testMethodSource(List<String) {

bookmark_borderInstalar mariadb 10.11 en Windows Server R12

Descarga la versión LTS de mariadb. Siempre prefiere las versiones LTS a las versiones mas nuevas, a menos cuando vaya a salir tu aplicación ya este en funcionamiento la versión LTS.

La versión para descargar la puedes encontrar en https://mariadb.com/downloads/, selecciona la versión y el sistema operativo.

Ejecuta el programa, vas a tener que tener a la mano los siguientes datos.

  • Contraseña de root que va a tener el servidor.
  • De preferencia que no acepte conexiones con el usuario de root.
  • Directorio donde se va a instalar los programas y ruta donde se van a generar los archivos de datos.
  • Puerto por el cual va a escuchar, por default es el 3306, de preferencia debes de cambiarlo.

Acepta las preferencias, y deja que el programa continue.

Crea un usuario dbo (Database Server Owner) que tenga los privilegios para administrar la instancia que acabas de crear.

Abre una ventana de comando de mariadb, por default va a ser el usuario root, pon la contraseña con la cual configuraste la instancia y ejecuta.

mysql> CREATE USER 'admin'@'%' IDENTIFIED BY 'supersecretpassword';
mysql> GRANT ALL PRIVILEGES ON * . * TO 'admin'@'%';
mysql> FLUSH PRIVILEGES;

Con eso vas a poder conectarte y administrar la instancia desde cualquier maquina con el usuario que acabas de crear

Para que este seguro tu servidor solo debes de exponer los puertos que tu controles, por lo que te sugiero que instales un firewall en tu servidor de windows.

bookmark_borderInstalar servidor NGINX en Ubuntu Server 22.04

Instala desde el repositorio de Ubuntu

  • Instala desde el repositorio de Ubuntu
sudo apt update
sudo apt install nginx
  • Actualiza el firewall
sudo ufw app list
sudo ufw allow 'Nginx FULL'
sudo ufw status
  • Verifica que se haya instalado el servidor correctamente
sudo systemctl status nginx
http://mi_servidor
  • Actualiza los server blocks
sudo mkdir -p /var/www/mi_nuevo_dominio/html
sudo chown -R $USER:$USER /var/www/mi_nuevo_dominio/html
sudo chmod -R 755 /var/www/mi_nuevo_dominio
sudo nano /var/www/mi_nuevo_dominio/html/index.html
sudo nano /etc/nginx/sites-available/mi_nuevo_dominio

Crea el index.html con la siguiente plantilla que despues deberás cambiar

<html>
    <head>
        <title>Bienvenido a mi_nuevo_dominio!</title>
    </head>
    <body>
        <h1>Perfect!  El server block de mi_nuevo_dominio esta trabajando!</h1>
    </body>
</html>

Crea el archivo de configuración para tu nuevo dominio con la siguiente plantilla, esta la uso para aplicación SPA (Angular, React) ya que todo el redireccionamiento se hace del lado de cliente.

server {
        listen 80;
        listen [::]:80;

        root /var/www/mi_nuevo_dominio/html;
        index index.html index.htm index.nginx-debian.html;

        server_name mi_nuevo_dominio www.mi_nuevo_dominio;

        location / {
            index index.html;
            try_files $uri $uri/ /index.html =404;
        }
}
  • Familiarizate con los archivos y directorios mas importantes de NGINX
    • Contenido. Los sitios se almacenan en /var/www/, cada sitio se almacena en un directorio diferente y el sitio por default se almacena en /var/www/html
    • Configuración.
      • /etc/nginx: Directorio de configuración del servidor Nginx. Todos los archivos de configuración de Nginx se encuentran aqui.
      • /etc/nginx/nginx.conf: The main Nginx configuration file. This can be modified to make changes to the Nginx global configuration.
      • /etc/nginx/sites-available/: The directory where per-site server blocks can be stored. Nginx will not use the configuration files found in this directory unless they are linked to the sites-enabled directory. Typically, all server block configuration is done in this directory, and then enabled by linking to the other directory.
      • /etc/nginx/sites-enabled/: The directory where enabled per-site server blocks are stored. Typically, these are created by linking to configuration files found in the sites-available directory.
      • /etc/nginx/snippets: This directory contains configuration fragments that can be included elsewhere in the Nginx configuration. Potentially repeatable configuration segments are good candidates for refactoring into snippets.
    • Logs
      • /var/log/nginx/access.log: Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise.
      • /var/log/nginx/error.log: Any Nginx errors will be recorded in this log.

Fuente: https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04

bookmark_borderConfigurar un pipeline Jenkins para una aplicación Angular

Vamos a configurar un pipeline de Jenkins para desplegar una aplicación Angular en un contenedor Docker. Como casi siempre vamos a utilizar versiones LTS (Long Term Service). En el momento de escribir este articulo las versiones LTS que tenemos son las siguientes:

En que lo vamos a utilizar

  • Ubuntu server 22.04 LTS.
  • Jenkins Server 2 LTS
  • OpenJDK 17
  • Node 18 LTS
  • Angular 15
  • Docker 20.10

    Instalación Angular en el servidor

    Lo primero que vamos a hacer es instalar node en el servidor de Jenkins

    • Agrega la llave de Nodejs, y ejecuta el instalador de paquetes apt. Siempre consulta la llave correcta tomada de la pagina oficial de node.
    $ curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - &&\
    sudo apt-get install -y nodejs
    • Verifica que se haya instalado correctamente node
    $ node -v
    v18.16.0
    • Ahora instalamos Angular 15, y verificamos su instalación. (si no le pones la versión instalas la ultima versión que tenga en el npm)
    $ sudo npm install -g @angular/cli@15.2.8
    ...
    $ ng version
         _                      _                 ____ _     ___
        / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
       / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
      / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
     /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                    |___/
        
    Angular CLI: 15.2.8
    Node: 18.16.0
    Package Manager: npm 9.6.6
    OS: linux x64
    
    Angular: 16.0.1
    ... animations, common, compiler, compiler-cli, core, forms
    ... platform-browser, platform-browser-dynamic, router
    
    Package                         Version
    ---------------------------------------------------------
    @angular-devkit/architect       0.1600.1
    @angular-devkit/build-angular   16.0.1
    @angular-devkit/core            16.0.1
    @angular-devkit/schematics      15.2.8 (cli-only)
    @schematics/angular             15.2.8 (cli-only)
    rxjs                            7.8.1
    typescript                      5.0.4
    
    • Para este articulo vamos crear una app de prueba, y la vamos a subir a un repositorio para que de alli lo tome Jenkins.
    $ ng new angular-app-jenkins
    ...
    Successfully initialized git.
    
    $ cd angular-app-jenkins
    $ git init 
    $ git add .
    $ git commit -am "Version inicial"
    $ git remote add origin https://gitlab.com/luidasa/angular-app-jenkins
    • Creamos el archivo Dockerfile en el proyecto de Angular, para tener las instrucciones de empaquetamiento.
    ### STAGE 1:BUILD ###
    # Defining a node image to be used as giving it an alias of "build"
    # Which version of Node image to use depends on project dependencies 
    # This is needed to build and compile our code 
    # while generating the docker image
    FROM node:18.16-alpine AS build
    # Create a Virtual directory inside the docker image
    WORKDIR /dist/src/app
    # Copy files to virtual directory
    # COPY package.json package-lock.json ./
    # Run command in Virtual directory
    # Install npm 9.6.6 que es al momento de escribir este articulo la versión mas reciente.
    RUN npm install -g npm@9.6.6
    RUN npm cache clean --force
    # Copy files from local machine to virtual directory in docker image
    COPY . .
    RUN npm install
    RUN npm run build --omit=dev
    
    
    ### STAGE 2:RUN ###
    # Defining nginx image to be used
    FROM nginx:latest AS ngi
    # Copying compiled code and nginx config to different folder
    # NOTE: This path may change according to your project's output folder 
    COPY --from=build /dist/src/app/dist/domain-app-name /usr/share/nginx/html
    COPY ./nginx.conf /etc/nginx/conf.d/default.conf
    # Exposing a port, here it means that inside the container 
    # the app will be using Port 80 while running
    EXPOSE 80
    • Creamos el archivo Jenkinsfile en el proyecto de Angular
    /* Requires the Docker Pipeline plugin */
    pipeline {
        agent any
        environment {
          VERSION = '1.0'
        }    
        stages {
          stage('build') {
            steps {
              git url: 'https://gitlab.com/luidasa/angular-app-jenkins.git', branch: 'master', credentialsId: 'gitlab-luidasa'
              sh '/usr/bin/ng build --prod'
            }
          }
          stage('build image') {
            steps {
              sh 'docker build -t luidasa/angular-app-jenkins:${VERSION}.${BUILD_NUMBER} .'
            }
          }
          stage('push image to hub') {
            steps {
              withDockerRegistry([credentialsId: "dockerhub", url: ""]) {
                sh 'docker push luidasa/angular-app-jenkins:${VERSION}.${BUILD_NUMBER}'
              }
            }
          }
        }
    }
    • Por ultimo, configuramos jenkins

    bookmark_borderCambiar el nombre del server Ubuntu 22.04 lts

    Para cambiar el nombre del servidor en ubuntu 22.04 lts, se requiere realizar los siguientes pasos.

    Con hostnamectl

    Esta es una utilidad que casi siempre esta presente, sino instalala.

    • Verifica el nombre del servidor
    $ sudo hostnamectl
    • Cambia el nombre de forma permanente. Requiere que seas sudo
    $ sudo hostnamectl set-hostname pruebas.midominio.com

    Cambiando con comando hostname y archivos de configuración

    • Para cambiarlo de forma temporal y vuelve a su nombre cuando se cierra la sesión.
    $ hostname
    $ hostname pruebas.midominio.com
    • Para cambiarlo de forma permanente, requiere que tengas permisos de sudo. Edita el archivo hostname.
    $ sudo vi /etc/hostname
    
    ***
    pruebas.midominio.com
    
    • Modifica el archivo hosts
    $ sudo vi /etc/hosts
    
    ***
    
    127.0.0.1       localhost
    127.0.0.1       pruebas.midominio.com
    
    • Por ultimo, si es estas en un ambiente virtualizado es posible que tengas el archivo de configuración de la nube. Cambia la bandera para preservar el nombre en la maquina virtual
    $ sudo vi /etc/cloud/cloud.cfg
    
    ***
    
    .....
    
    preserve_hostname: true
    
    .....
    
    • Por ultimo reinicia el servidor, y vuelve a conectarte para validar los cambios.
    $ sudo reboot
    $ ssh pruebas.midominio.com
    usuario@pruebas: ~$ 

    bookmark_borderInstalar Jenkins 2 LTS en ubuntu 22.04 LTS

    Vamos a instalar Jenkins 2 LTS para producción. Nota siempre ocupamos para producción las versiones LTS (Long Term Service) para los ambientes de producción.

    En una consola de ingresa los siguientes comandos

    • Instalación de Java JDK 17 LTS
    sudo apt update
    sudo apt install openjdk-17-jdk
    java -version
    javac -version
    sudo update-alternatives --config java
    • Instala Maven, en el Filesystem recomendado.
    curl https://dlcdn.apache.org/maven/maven-3/3.9.0/binaries/apache-maven-3.9.0-bin.tar.gz --output apache-maven-3.9.0-bin.tar.gz
    tar xzvf apache-maven-3.9.0-bin.tar.gz
    sudo chown root:root -R /usr/bin/apache-maven-3.9.0
    
    • Instala GIT
    sudo apt update
    sudo apt install git
    • Instala Jenkins

    Descarga la llave para mantener la versión actualizada.

    $ curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
        /usr/share/keyrings/jenkins-keyring.asc > /dev/null
    $ echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
        https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
        /etc/apt/sources.list.d/jenkins.list > /dev/null
    $ sudo apt install jenkins
    • Instala CertBot

    • Configura Jenkins con CertBot

    bookmark_borderInstalar jdk 17 LTS en ubuntu server 22.04 LTS

    Descripción

    En una consola escribe la sentencia, para actualizar, buscar y en su caso instalar el openjdk desde el repository default de Ubuntu

    sudo apt update
    sudo apt search openjdk-17-jdk
    sudo apt install openjdk-17-jdk

    Verifica que se haya instalado la versión con el siguiente comando

    java -version
    javac -version

    Si tienes varias versiones de java configura la que se va a ocupar por default

    sudo update-alternatives --config java

    bookmark_borderRenovar el certificado de keycloak

    Habia instalado keycloak con una imagen de docker y le puse un certificado hecho con certbot. El problema que ahora veo es que los certificados de cerbot solo tienen una vigencia de 3 meses, por lo tanto, unos dias antes de que expire hay que renovar el certificado y volver a pasarlo al contenedor de keycloak.

    Bueno en este articulo voy a describir los pasos que realice para renovar y automatizar la renovación de los certificados de certbot.

    Versiones

    Esto utilizando las siguientes versiones.

    • Ubuntu server 22.04
    • Docker version 20.10.8, build 3967b7d
    • certbot 1.32.2
    • KEYCLOAK_VERSION=15.0.0

    Procedimiento

    • Crea un nuevo certificado con certbot
    $ sudo certbot certonly --manual -d keycloak.yourdomain.com
    [sudo] contraseña para username: 
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Certificate not yet due for renewal
    
    You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
    (ref: /etc/letsencrypt/renewal/keycloak.yourdomain.com.conf)
    
    What would you like to do?
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    1: Keep the existing certificate for now
    2: Renew & replace the certificate (may be subject to CA rate limits)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
    Renewing an existing certificate for keycloak.yourdomain.com
    
    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/keycloak.yourdomain.com/fullchain.pem
    Key is saved at:         /etc/letsencrypt/live/keycloak.yourdomain.com/privkey.pem
    This certificate expires on 2023-04-12.
    These files will be updated when the certificate renews.
    
    NEXT STEPS:
    - This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    If you like Certbot, please consider supporting our work by:
     * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
     * Donating to EFF:                    https://eff.org/donate-le
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    • Deten el contenedor de keycloak
    $ docker stop keycloak
    keycloak
    • Borra el contenedor de keycloak, asegurate de tener:
      • Configurada la base de datos fuera de tu contenedor
      • El script de creación del contenedor con la configuración de las variables de sesión.
    $ docker rm keycloak
    keycloak
    • Vuelve a crear el contenedor con el script de creación que tenias.
    docker run -it -d --name keycloak --net keycloak-network -p8080:8080 -p 8443:8443 -v /etc/letsencrypt/live/keycloak.yourdomain.com/fullchain.pem:/etc/x509/https/tls.crt -v /etc/letsencrypt/live/keycloak.yourdomain.com/privkey.pem:/etc/x509/https/tls.key -e KEYCLOAK_USER=administrador -e KEYCLOAK_PASSWORD=yourkeycloakpassword -e DB_VENDOR=mariadb -e DB_DATABASE=keycloak -e DB_USER=keycloak -e DB_PASSWORD=your-db-password jboss/keycloak
    • Asegurate de que la llave privada y la llave publica, el agente de docker tenga permisos para su ejecución.