sábado, 1 de junho de 2013

MD5 com External Object

O Genexus X sofreu uma tremenda evolução, sob o ponto de vista do desenvolvedor, é claro, quando resolveu deixar que coisas externas pudessem ser encaixadas nos projetos, de forma, digamos, 'mais' natural. Porque nas versões anteriores o que tínhamos era uma ferramenta mais 'dura' e restritiva ao seu modelo mais conceitual, que consistia em entregar um conjunto de funcionalidades que pudessem ser utilizadas para programar seus sistemas, isto sem a necessidade de compreender ou utilizar códigos nativos.

E isso, claro, tem uma importante razão de ser, pois Genexus busca até hoje retirar do desenvolvedor o peso de ter que entrar no nível da programação mais manual, ou seja reduzir seu trabalho, mas como sabemos, algumas situações ainda exigem um pouco de 'intervenção', principalmente naquelas onde a ferramenta não atua de forma direta.

Assim entrou em cena um recurso tremendamente importante chamado External Object, que pode ser traduzido como: 1) a flexibilidade de incorporar em seu projeto uma DLL ou classe Java escrita externamente em outra ferramenta que não o Genexus. Ou pelos sinonimos, 2) permitir acessar Stored Procedures, Java Sessions Beans, Webservices, ...

Não vou ficar aqui discutindo a filosofia do desenvolvimento Tradicional x Genexus, mas que fique bem claro que quando se utiliza esse recurso seu projeto fica meio 'amarrado' na plataforma escolhida, portanto, cautela. Não vá saindo programando tudo externamente, Genexus ainda é a melhor opção em 99,99% dos casos.

Então, vamos a um exemplo prático.

MD5

Todos sabemos a importância de utilizarmos encriptação em nossos sistemas, que escondam informações relevantes para o caso do pior acontecer.  MD5 é um desses recursos, e que encontra muitas aplicações em nossos projetos, como por exemplo, esconder senhas de bisbilhoteiros.  O detalhe apenas é que esse algoritmo também esconde a informação de nós mesmos, pois uma vez encriptado não tem volta ao valor original.

Genexus não possui um algoritmo próprio MD, mas podemos incorporá-lo facilmente a nosso projeto com o tal External Object. Você precisa de uma classe Java ou DLL (em C#) que realize esta tarefa, e um objeto que realize a conexão com o Genexus.

Para fins de teste, vou utilizar o exemplo do MSDN da classe que realiza essa operação, que se encontra em http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx,  o qual pegamos, criamos um projeto no Visual Studio e adaptamos um pouco o código, e que assim ficou.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace MD5Lib {
    public class MD5Library
    {
        private MD5 md5Hash = MD5.Create();
        public string GetMd5Hash(string input)
        { 
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)  {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }

        public bool VerifyMd5Hash(string input, string hash)
        {
            string hashOfInput = GetMd5Hash(input);
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;
            if (0 == comparer.Compare(hashOfInput, hash)){
                return true;
            }
            else {
                return false;
            }
        }
    }
}

 
Olhando bem, não tem muito segredo isso ai, simples de fazer, e não fique triste se você gostaria de ver isso em Java, basta procurar na internet que terá um exemplo de classe semelhante a essa facilmente.
 
Após compilar essa classe no Visual Studio, com o .Net Framework 3.5, e obter o md5.dll, (colocamos o link ai para você baixá-la, se quiser economizar tempo) podemos partir para o Genexus para utilizá-la em nosso sistema.

 

Importando a Classe Externa


Agora a parte mais simples, que é incorporar a classe no Genexus, que conta com uma ferramenta que importa e configura a classe para nosso uso, basta seguir os passos a seguir.
  1. Copie a biblioteca md5.dll na pasta BIN do seu projeto
  2. Para isso, chame a ferramenta Tools->Application Integration, e selecione o tipo .Net Assembly Import
  3. Na janela abra o seletor de arquivos e aponte para o nosso MD5.dll, nesta pasta BIN, portanto, descubra primeiro onde se encotnra essa pasta (Tools->Explore Target Environment Directory)
  4. Na janela Select Object Parameters, pressione Next
  5. Na janela Select Classes, selecione a classe MD5Library
  6. Selecione a Classe MD5Library e os métodos GetMd5Hash e VerifyMd5Hash
  7. Pressione FINISH


 O Genexus criará o External Object nessa operação.

Usando o External Object

Enfim, depois de todo esse esforço podemos testar a coisa, criando um simples Webpanel, e uma variável do tipo Md5Library, sim, podemos criar uma variável (objeto) a partir dessa classe importada externamente.  Algo semelhante ao que foi escrito em Genexus a seguir, que pega uma palavra qualquer 'teste'e a encripta.

Event Start

 // gera um valor MD5 para um texto qualquer: teste 
 &md5gerado = &MD5Library.GetMd5Hash('teste')
 msg(&md5gerado )


 // verifica se a palavra 'teste' foi gerada corretamente
 &resultado = &MD5Library.VerifyMd5Hash('teste', &md5gerado )
 if &resultado
  msg('ok!')
 else
  msg('não ok!')
 endif

EndEvent

Por meio dessa variável podemos acessar os dois métodos criados externamente. O primeiro GetMd5Hash gera a encriptação, e o VerifyMd5Hash que verifica se certo valor (que foi encriptado anteriormente) corresponde ao texto, permitindo que testemos o valor encriptado.

Levando isso para um processo de teste de senha, seria algo assim:
  1. Quando tiver a senha do usuário encripte (GetMd5Hash) e grave o valor resultante no BD (UsuarioSenha)
  2. Quando a pessoa digitar a senha (&SenhaDigitada) avalie o valor armazenado no banco com o texto digitado, algo como: &MD5Library.VerifyMd5Hash(&SenhaDigitada, UsuarioSenha)

Conclusão

Creio que esse recurso revoluciona, pois permite aliar a potência das linguagens nativas (Java, C#) com a potência do Genexus em manipular tabelas, construir aplicações automáticas, ou seja, temos a possibilidade de construir aplicações absurdamente interessantes de forma rápida e eficiente.

Para os iniciantes em Genexus, no entanto, recomendo que tome muito cuidado para não querer fazer tudo na linguagem nativa, pois muitos vieram deste mundo tradicional e, claro, possuem mais segurança nas linguagens em que programava. Melhor é aprender Genexus, utilizar todo seu potencial, e nas situações em que este não atender, buscar essa alternativa. Digo isso porque quanto mais nativa for nossa aplicação, mais difícil será migrá-la para outros Environments, e com certeza não queremos perder essa flexibilidade ao trabalharmos com projetos Genexus.






Ps: mais uma pequena contribuição, caso queira o codigo (xpz) do exemplo + a Dll (md5.dll), pode baixar aqui.