quarta-feira, 8 de junho de 2022

Gerenciando Certificados SSL da Máquina

 Atualmente as conexões https utilizam certificados SSL. Em alguns casos também são utilizadas conexões TLS com dupla validação. Quando o acesso a um site, que necessita de um nível mais alto de segurança, utiliza um certificado para liberar o acesso. Também é comum precisarmos instalar certificados para acessar uma aplicação para desenvolver algum código evitando bloqueios e telas brancas.

Geralmente realizamos um import de um certificado via linha de comando como exemplo abaixo:

keytool -import -trustcacerts -keystore /jdk/jre/lib/security/cacerts -storepass changeit -noprompt -file /Downloads/nomeCertificado.cer -alias nomeDoCertificado

Esse tipo de import leva o certificado importado sempre para o endereço onde está o Java em: /jre/lib/security/cacerts dentro deste arquivo cacerts.

É necessário atenção para quando de usa mais de uma versão de Java na mesma máquina.

Da mesma forma é possível apagar o certificado importado desde que se saiba o alias, neste caso:

keytool -delete -alias <ALIAS_DO_CERTIFICADO_A_SER_REMOVIDO> -keystore <PATH_CACERTS>

Por exemplo:

 keytool -delete -alias nomeDoCertificado -keystore  /jdk/jre/lib/security/cacerts

Utilize sempre a senha: changeit

Agora, para visualizarmos os certificados importados podemos utilizar o Portecle, baixe de uma fonte segura como Sourceforge:

https://sourceforge.net/projects/portecle/

Execute o portecle.jar dentro do sistema de arquivos, deverá abrir uma janela:


Clique na pasta para abrir e selecione o endereço do Cacerts na sua máquina: /jdk/jre/lib/security/cacerts

Utilize a mesma senha já passada.

Deverá abrir a janela abaixo:


Clicando duas vezes no certificado é possível ver os detalhes dele. Dessa forma podemos verificar se um certificado foi importado corretamente ou não.


terça-feira, 7 de junho de 2022

Preenchimento Automático de Formulários Utilizando Atalho de Favoritos do Navegador

Quando temos um formulário que preenchemos repetidamente com os mesmo dados, é possível criar um atalho na barra de menu do Navegador.
Para isso, vamos adicionar um novo atalho qualquer clicar com o botão direito e editar o atalho:



A tela que deverá abrir será a seguinte:


Vamos editar os campos Nome e URL. Podemos dar um novo nome para o atalho como "Completa Form":





Agora vamos supor um formulário com 3 campos. Precisaremos dos ids, no código fonte, dos 3 campos que nesse caso é possível utilizar o botão direito do mouse e "inspecionar" o campo para ver os id's. No nosso código temos os id's nome, telefone e idade.



Vamos utilizar um comando javascript para cada campo:

document.getElementById('nome').value = 'Marcelo';
document.getElementById('telefone').value = '999999999';
document.getElementById('idade').value = '99';

Agora, para fechar vamos colocar numa chamada Javascript conforme abaixo:

javascript:(function(){..código..})();

Sem espaçamento e em uma única linha o código completo ficará da seguinte forma:

javascript:(function(){document.getElementById('nome').value = 'Marcelo';document.getElementById('telefone').value = '999999999';document.getElementById('idade').value = '99';})();

Copie o código e cole no campo da URL do atalho:



Agora a página com o formulário que deve ser preenchido:


Clique no atalho "Completa Form" e os dados serão preenchidos instantaneamente:


É possível submeter o envio também se for necessário:

document.getElementById("idBotaoEnvio").submit();

Também é possível utilizar JQuery para códigos com JQuery, nesse caso utilizaríamos:

var campo1 = 'valor1';$("#campo1").val(campo1);

E para o envio:

$(#button).click();



segunda-feira, 6 de junho de 2022

Configurando Chave SSH para Git

 Para utilizar o git para subir código através de SSH é necessário sempre ter uma chave configurada previamente. Para configurar a chave é simples. Acesse a pasta do seu usuário na máquina e verifique se existe uma pasta .ssh criada, se a pasta não existir é porque não existe chave configurada. Para configurar utilize o clique do botão direito no desktop mesmo e acesse seu git bash:


Em seguida execute no prompt o comando que deverá criar uma chave na pasta C:/Usuário/<seu_usuario>/.ssh com um arquivo com o conteúdo de uma chave criptografada, conforme abaixo:

ssh-keygen -o -f ~/.ssh/id_rsa



Após a execução, será solicitado uma palavra passe, digite-a e tecle enter. A palavra é solicitada 2 vezes:


Após a execução:


Acesse o arquivo .pub no diretório e abra com o editor de texto. Copie a chave que deve começar com ssh-rsa.

  

Acesse seu repositório git e adicione a nova chave nas configurações de SSH do seu perfil.

No caso do Github em Configuraões>SSH:



No caso do Gitlab em /profile/keys.

Ao baixar o projeto copie a opção de repositório SSH para fazer o clone:



Ao executar o git clone será solicitada a chave SSH que foi configurada. O mesmo para Push e Pull.



quinta-feira, 10 de setembro de 2020

Código WebRTC para Captura de Imagem via WebCam

 Segue um código simples para capturar imagem através de WebRTC. O WebRTC (Real Time Comunications) é um protocolo que pode ser utilizado em vários navegadores com exceção do Safari. Também é Web Responsivo para ser utilizado para capturar a imagem da câmera dos celulares e também de notebooks (desktop) além da RaspberiPI. O código roda em HTML5 com Javascript e possui restrições para IOs. A documentação possui uma parte do código mas o código não está completo. Segue o código corrigido e também as referencias da documentação:


Crie um arquivo html com o conteudo abaixo:


<div id="screenshot" style="text-align:center;">

  <video class="videostream" autoplay></video>

  <img id="screenshot-img">

  <p><button class="capture-button">Capture video</button>

  <p><button id="screenshot-button" disabled>Take screenshot</button></p>

</div>



<script>

const constraints = {

  video: true

};

const captureVideoButton =

  document.querySelector('#screenshot .capture-button');

const screenshotButton = document.querySelector('#screenshot-button');

const img = document.querySelector('#screenshot img');

const video = document.querySelector('#screenshot video');


const canvas = document.createElement('canvas');


captureVideoButton.onclick = function() {

  navigator.mediaDevices.getUserMedia(constraints).

    then(handleSuccess).catch(handleError);

};


screenshotButton.onclick = video.onclick = function() {

  canvas.width = video.videoWidth;

  canvas.height = video.videoHeight;

  canvas.getContext('2d').drawImage(video, 0, 0);

  // Other browsers will fall back to image/png

  img.src = canvas.toDataURL('image/jpeg');

 

};


function handleSuccess(stream) {

  screenshotButton.disabled = false;

  video.srcObject = stream;

}

</script>


Referencias:

Documentação da Google https://developers.google.com/web/fundamentals/media/capturing-images?hl=pt-br 

HTML5 Rocks https://www.html5rocks.com/en/tutorials/getusermedia/intro/

Compatibilidade http://iswebrtcreadyyet.com/



quarta-feira, 19 de fevereiro de 2020

Criando um Projeto Angular com PrimeNG

O PrimeNG é uma versão do antigo Primefaces para o Angular. A documentação pode ser acessada em:

https://primefaces.org/primeng/#/

Quando estamos criando um novo projeto executamos alguns passos sequencialmente. A etapa de inicio de um novo projeto muitas vezes consiste em executar tais passos exaustivamente para criar diversos projetos a fim de executar testes isolados. Para facilitar essa tarefa resolvi fazer esse post, para ter os passos sequenciais de criação de projeto descritos, para acessar de forma fácil e não ter que ficar procurando os comando toda vez que se cria um novo projeto, então segue a sequencia abaixo.

Os passos foram executados em uma máquina Windows.

Inicialmente verifique se o Nodejs já está instalado.

Verificar se o node está instalado
> node -v

Instalar a última versão de angular CLI usado para instalação automática de pacotes via linha de comando

Instala o CLI Angular
> npm install -g @angular/cli@latest

Cria um novo projeto Angular
> ng new nomeProjeto

Acessa a pasta do projeto
> cd nomeProjeto

Para levantar o servidor dentro da pasta do projeto
> ng serve

ctrl+c para encerrar o servidor

Instalar o Primeng
> npm install primeng --save

Intalar Prime Icons
> npm install primeicons --save

No arquivo angular.json do projeto criado insere em style o bloco primeng conforme a documentação Get Started.

"styles": [
"src/styles.css",
"node_modules/primeicons/primeicons.css",
"node_modules/primeng/resources/themes/nova-light/theme.css",
"node_modules/primeng/resources/primeng.min.css"
],


Feito isso, temos um projeto Angular com PrimeNG preparado para testes.

Documentação PrimeNG Get Started:


quinta-feira, 23 de janeiro de 2020

Gerando Script para Habilitar e Desabilitar Constraints de Tabela

Para melhor manusear tabelas de uma base de dados, de forma mais veloz, sem ter que ficar percorrendo as outras tabelas que são referenciadas na primeira, é possivel desabilitar as constraints. Atenção para não gerar dados corrompidos conforme a operação que for realizada depois disso.

Rode o script abaixo preenchendo o nome da tabela e o owner e na saída serão gerados os scripts a serem executados.




  1. SELECT 'alter table '||cons.owner||'.'||cons.table_name||' disable constraint '||cons.constraint_name||'; ' -- para habilitar so trocar o desable para enable
  2.  
  3. FROM dba_constraints      col,
  4.  
  5.    dba_constraints       cons
  6.  
  7. WHERE cons.r_owner = col.owner
  8.  
  9. AND cons.r_constraint_name = col.constraint_name
  10.  
  11. AND cons.constraint_type = 'R'
  12.  
  13. AND col.table_name IN( 'TB_CARROS') -- colocar tabelas que vai truncar aqui
  14.  
  15. AND col.owner = 'NOME_DO_ACESSO'
  16.  
  17. ORDER BY cons.table_name;



A partir deste script é possível criar um script único para habilitar ou desabilitar todas as constraints da base de dados.

Esse tipo de procedimento é interessante para iniciar uma limpeza geral na base de dados antes da subida em produção quando nem todas as tabelas devem ser limpas.



terça-feira, 6 de fevereiro de 2018

Limpeza de Cache do Chrome

Por vezes, rodamos uma aplicação e alguns problemas de carregamento de css e Javascript acontecem de forma comum. Segue uma forma de limpar o cache no Chrome. Abra duas abas do Chrome e digite no campo de url:





chrome://net-internals/#dns




Em seguida, basta clicar:



clear host cache







chrome://net-internals/#sockets



Em seguida, basta clicar:



flush socket pulls

sexta-feira, 30 de setembro de 2016

Internacionalização no Spring-Boot

Conforme prometido, vamos falar sobre I18n no Spring-Boot. Vamos utilizar o mesmo projeto das postagens anteriores:
http://toxinavirtual.blogspot.com.br/2016/09/crud-com-rest-spring-boot-e-jpa.html

Vamos criar os arquivos com as labels em Inglês, Espanhol e Português em arquivos diferentes com as diferentes traduções. Os arquivos deverão ficar dentro de uma pasta nova chamada de i18n que será criada dentro de resources. Os arquivos são de texto do tipo .properties.


No arquivo messages_en.properties, o conteúdo:
  1. field1 = My Field 1
  2. field2 = My Field 2



No arquivo messages_es.properties, o conteúdo:
  1. field1 = El Campo 1
  2. field2 = El Campo 2



No arquivo messages_pt.properties, o conteúdo:
  1. field1 = Meu Campo 1
  2. field2 = Meu Campo 2


Vamos criar agora o template hello.html dentro da pasta resources/template. O arquivo dever[a conter o seguinte:
  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
  3. <head lang="en">
  4.     <meta charset="UTF-8" />
  5.     <title>HELLO</title>
  6. </head>
  7. <body>
  8.     <div>
  9.         <label for="field1" th:text="#{field1}"></label>
  10.         <input type="text" id="field1" name="field1" />
  11.     </div>
  12.     <div>
  13.         <label for="field2" th:text="#{field2}"></label>
  14.         <input type="text" id="field2" name="field2" />
  15.     </div>
  16.     <div>
  17.         <button type="submit">Save</button>
  18.     </div>
  19. </body>
  20. </html>

Repare que no template temos os campos em variáveis delimitadas por "#{}". O texto com o nome da variável deverá ser substituído pelas traduções dos arquivos properties.

O arquivo de template está usando um gerenciador de templates para que o Spring-Boot consiga interpretar o arquivo. Será necessário adicionar a dependência dentro do arquivo pom.xml.


  1.         <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  4.         </dependency>



O template também depende de um controlador que determine a rota de acesso.

  1. package com.example.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.ui.Model;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. @Controller
  6. public class Hello {
  7.     @RequestMapping("/hello")
  8.     public String gohome(Model model){
  9.         return "hello";
  10.     }
  11.    
  12. }


A classe mapeada para o endereço /hello deverá retornar o nome do template sem a necessidade a da extensão .html. O conteúdo do arquivo será exibido, mas por enquanto sem a tradução.



Para implementar a tradução precisaremos extender o arquivo de inicialização para a classe WebMvcConfigurerAdapter. Como o arquivo de inicialização está extendendo o deploy criaremos um novo arquivo de configuração que funcionará paralelamente.


Com as anotations @Configuration, @EnableAutoConfiguration e @ComponentScan o Spring-Boot já saberá que se trata de um arquivo de configuração que possui componentes de configuração.


Primeiramente, criaremos um Locale. O Locale determina a linguagem através da região em que o site é acessado, assim como ajuda na configuração da tradução. O Locale geralmente fica armazenado na sessão do sistema.

  1.     //I18n do pacote web.servlet
  2.     @Bean
  3.     public LocaleResolver localeResolver() {
  4.         SessionLocaleResolver slr = new SessionLocaleResolver();
  5.         slr.setDefaultLocale(Locale.US);
  6.         return slr;
  7.     }

Agora criamos um interceptador do parâmetro de linguagem.
  1.     @Bean
  2.     public LocaleChangeInterceptor localeChangeInterceptor() {
  3.         LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
  4.         lci.setParamName("lang");
  5.         return lci;
  6.     }
  7.     //I18n
  8.     @Override
  9.     public void addInterceptors(InterceptorRegistry registry) {
  10.         registry.addInterceptor(localeChangeInterceptor());
  11.     }


Em seguida criamos um MessageSource e definimos o arquivo de origem da mensagem. O Validator vai executar a troca.

  1.     @Bean
  2.     public MessageSource messageSource() {
  3.         final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
  4.         messageSource.setBasename("classpath:/i18n/messages");
  5.         messageSource.setUseCodeAsDefaultMessage(true);
  6.         messageSource.setDefaultEncoding("UTF-8");
  7.         return messageSource;
  8.     }
  9.    
  10.     @Override
  11.     public Validator getValidator() {
  12.         LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
  13.         validator.setValidationMessageSource(messageSource() );
  14.         return validator;
  15.     }
  16. }

Segue o arquivo na integra:
  1. package com.example.config;
  2. import java.util.Locale;
  3. import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  4. import org.springframework.context.MessageSource;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.ComponentScan;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.support.ReloadableResourceBundleMessageSource;
  9. import org.springframework.validation.Validator;
  10. import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
  11. import org.springframework.web.servlet.LocaleResolver;
  12. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  13. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  14. import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
  15. import org.springframework.web.servlet.i18n.SessionLocaleResolver;
  16. @Configuration
  17. @EnableAutoConfiguration
  18. @ComponentScan
  19. class ApplicationConfig extends WebMvcConfigurerAdapter  {
  20.    
  21.     //I18n do pacote web.servlet
  22.     @Bean
  23.     public LocaleResolver localeResolver() {
  24.         SessionLocaleResolver slr = new SessionLocaleResolver();
  25.         slr.setDefaultLocale(Locale.US);
  26.         return slr;
  27.     }
  28.    
  29.     //I18n
  30.     @Bean
  31.     public LocaleChangeInterceptor localeChangeInterceptor() {
  32.         LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
  33.         lci.setParamName("lang");
  34.         return lci;
  35.     }
  36.     //I18n
  37.     @Override
  38.     public void addInterceptors(InterceptorRegistry registry) {
  39.         registry.addInterceptor(localeChangeInterceptor());
  40.     }
  41.     @Bean
  42.     public MessageSource messageSource() {
  43.         final ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
  44.         messageSource.setBasename("classpath:/i18n/messages");
  45.         messageSource.setUseCodeAsDefaultMessage(true);
  46.         messageSource.setDefaultEncoding("UTF-8");
  47.         return messageSource;
  48.     }
  49.    
  50.     @Override
  51.     public Validator getValidator() {
  52.         LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
  53.         validator.setValidationMessageSource(messageSource() );
  54.         return validator;
  55.     }
  56. }

Segue a imagem da label funcionando.





 É possível ainda melhorar o projeto de várias formas, como definir a liguagem na sessão antes do login.

Mais tarde atualizo o post com o código do github.