Ferramentas do usuário

Ferramentas do site


infotic:projetos:mockcas

Tutorial para simular localmente o SSO CASino utilizando Docker

Este tutorial tem por objetivo criar um servidor local que responda de forma semelhante ao servidores CAS disponíveis em ambiente externo, mas possa ser configurado localmente.

Será abordada a construção da imagem na plataforma docker, sua execução e a configuração dos logins no SSO.

É necessário ter algum conhecimento prévio sobre docker e ciência de quais campos que virão das contas do SSO.

1. Construção da imagem docker

Os arquivos para a construção da imagem estão disponíveis no git.

Criaremos a imagem no docker e levantaremos o container com a imagem.

1.1. Baixar os arquivos disponíveis

$ git clone https://git.ufrj.br/josueresende/mock-casino.git
Descrição dos Arquivos
\Dockerfile Receita para a geração da imagem com Ruby 2.3 Foi utilizado como base em um projeto1) no site hub do docker.
\Gemfile Descreve as dependências para o programa em Ruby
\cas.yml Configuração de autenticadores e logins do programa
\database.yml Utilizado durante a instalação
\certificate_authority-password_1234-privateKey.key Chave privada da 'Certificate Authority' - senha: 1234
\certificate_authority-help.txt Informações sobre a criação da 'Certificate Authority' e ajuda para os testes em Java
\certificate_authority-rootCertificate.pem Certificado da 'Certificate Authority'
\certificate_authority-rootCertificate.srl Arquivo com o serial criado (-CAcreateserial )
\casino.key Private Key - Chave privada para o serviço
\casino.csr Certificate Signing Request
\casino.ext Extra - Dados para geração do certificado do serviço pela autoridade certificadora
\docker-entrypoint.sh Shell Script para gerar o certificado do serviço durante inicialização do container, alterando a linha IP.1 de acordo com o IP da máquina

Há como substituir os arquivos ou diretórios através da montagem de volumes quando for levantar o container mais à frente.

O certificado SSL será gerado durante a inicialização do container.

1.2. Construindo a imagem no docker

$ sudo docker image build --tag=mock-casino-image mock-casino

Obs: Favor reportar quaisquer problemas na geração da imagem.

1.3. Levantando o container utilizando a imagem criada

Ao levantar o container, é possível vincular os arquivos internos a arquivos externos informando como volume.

Podemos vincular um arquivo de configuração ‘cas.yml’ externo para aquele que se encontra dentro do container em /var/www/app/casino_app/config/cas.yml.

Para configurar esse arquivo externo, veja a seção Configurando logins no CASino.

Abaixo, assumirei que o arquivo externo existe em: /mnt/fs_docker/mocks/cas.yml.

Através da linha de comando do docker2) levantamos o container. Obs: Abaixo temos apenas uma linha de comando.

$ sudo docker container run
       --name=mock-casino-container
       --detach
       --volume=/mnt/fs_docker/mocks/cas.yml:/var/www/app/casino_app/config/cas.yml
       --publish=443:443
       mock-casino-image

1.4. Testando o CAS

Entre no seu browser, através do endereço https://127.0.0.1.

Se estiver correto irá aparecer a tela a seguir.

2. Configurando logins no CASino

O arquivo de configuração do SSO CASino3), cas.yml, está em YAML4) que é o formato utilizado como padrão de serialização em Ruby.

Para termos o arquivo modificado, altere ou copie o cas.yml baixado .

Nesse arquivo, iremos alterar a coleção ‘users’ onde a chave é o login e abaixo ficam os campos de cada usuário. As partes exibidas abaixo são apenas um trecho do arquivo completo.

development:
  <<: *defaults
    authenticators:
      static:
        class: "CASino::StaticAuthenticator"
        options:
        users:
          "login-do-usuario":
            nome: "nome-do-usuario"
            password: "senha-do-usuario"
            email: "email-do-usuario"
            outro-campo: "bla bla bla ..."
          "login-do-usuario-2":
            nome: "nome-do-usuario-2"
            password: "senha-do-usuario-2"
            email: "email-do-usuario-2"
            outro-campo: "bla bla bla ..."

Modifique os campos do usuário na lista 'users' com os campos esperados respeitando a indentação.

O único campo obrigatório é o password, que serve para autenticar e não retorna na resposta.

  users:
    "12345678909":
      nome: "JOAQUIM SILVA XAVIER"
      password: "123"
      email: "joaquimxavier@dominio.br"
      IdentificacaoUFRJ: "12345678909"
      matricula_siape: "123"
      registro_sira: "123"
      grupos: "tecnico_admin:aluno_pos"
      eh_tec_admin: "1"
      eh_aluno_grad: "---..."
      eh_aluno_pos: "0"
      eh_professor: "---..."
      ativo: "1"

É necessário reiniciar o SSO CASino para que as mudanças tenham efeito.

Obs: Para quem usa o CAS para autenticação e pega o perfil de usuário que vem de lá, a melhor maneira é pegar pelo atributo “grupos”, e ali terá uma string com todos os perfis que o usuário já teve na UFRJ. Os atributos “eh_<perfil>” só indicam se está em atividade no perfil.

3. Testes no ambiente com Laravel Dusk

Após as instalações do Dusk5) e execução do Chromedriver podemos realizar testes no ambiente.

Nosso .env.dusk terá pelo menos as seguintes linhas

# utilizo essa variável no script
CHROMEDRIVER=http://172.18.0.1:9515 
ROOT_USERNAME=12345678912
ROOT_PASSWORD=123
 
# abaixo seguem as utilizadas no projeto (.env)
APP_ENV=dusk
APP_DEBUG=true
APP_URL=http://172.18.0.10/
 
CAS_HOST=172.18.0.30
CAS_CONTEXT=""
CAS_PROXY=true

Para esta classe de teste,vamos sobrescrever criar os métodos driver/prepare/setUp na classe DuskTestCase, e incluir mais um método que insere o texto no input e confere seu valor.

...
    use Facebook\WebDriver\WebDriverBy;
    use Facebook\WebDriver\Chrome\ChromeOptions;
    use Facebook\WebDriver\Remote\DesiredCapabilities;
    use Facebook\WebDriver\Remote\RemoteWebDriver;
    .
    .
    .
    protected function driver()
    {
        $options = new ChromeOptions();
        $options->addArguments([
            '--disable-gpu',
            '--window-size=1920,1080',
            '--verbose',
            '--lang=pt-BR', // idioma do browser
            // '--headless', // <- browser sem tela
        ]);
        $options->setExperimentalOption(
            'prefs', 
            ['intl.accept_languages' => 'pt-BR']
        );
        return RemoteWebDriver::create(
            env('CHROMEDRIVER', NULL), 
            DesiredCapabilities::chrome()->setCapability(ChromeOptions::CAPABILITY, $options)
        );
    }
    public static function prepare()
    {
        static::startChromeDriver();
    }
    protected function setUp()
    {
        $this->browse( function (Browser $browser) {
            $browser->visit(env('APP_URL', '')); 
            # Fig: 1
            //            $browser->resize( 640, 480); sleep(5); // redimensionamentos de tela
            //            $browser->resize( 800, 600); sleep(5);
            //            $browser->resize(1024, 768); sleep(5);
            $browser->maximize();
            sleep(1);
            // 
            { // parte da rotina para fechar a DEBUGBAR
                $buttonDebugBares = $browser->driver->findElements(
                    WebDriverBy::className('phpdebugbar-close-btn')
                );
                foreach ($buttonDebugBares as $buttonDebugBar) { 
                    if ($buttonDebugBar->isDisplayed()) $buttonDebugBar->click(); 
                }
                if (count($buttonDebugBares) > 0) sleep(2);
            }
        });
        return parent::setUp(); // TODO: Change the autogenerated stub
    }
...
    // rotina que confere a digitação do texto em input
    protected function entrarDadosCorretamente($id, $value)
    {
        $this->browse( function (Browser $browser) use($id, $value) {
            do {
                $browser->type($id, $value);
                sleep(1);
                if ($browser->inputValue($id) == $value) break;
            } while(true);
        });
    }
...
    /**
     * @group T00
     * @group US01-0
     * @throws \Throwable
     */
    public function test_Login_no_CAS()
    {
        $username = env('ROOT_USERNAME');
        $password = env('ROOT_PASSWORD');
        $this->browse( function (Browser $browser) use($username, $password) {
            $browser->assertSee('Acesso administrativo');
            $browser->clickLink('Acesso administrativo'); 
            # Fig: 2
            self::entrarDadosCorretamente('username', $username);
            self::entrarDadosCorretamente('password', $password);
            $browser->click('button[type=submit]'); 
            # Fig: 3
            $browser->assertDontSee('Acesso administrativo');
        });
    }

Passos na figuras a seguir, em ordem:

Figura 1 - setUp Figura 2 - test_Login_no_CAS() após click no link de acesso Figura 3 - test_Login_no_CAS() após submit

As telas acima são do projeto Novo Conhecendo a UFRJ.


Anexo: Portainer – Docker Compose file format v2

Para execução do container no portainer editamos a stack que utilizará o mock.

Abaixo como exemplo na sua seção services6), segue:

casino:
   container_name: mock-casino-container
   hostname: casino
   image: mock-casino-image
   restart: unless-stopped
   mem_limit: 1G
   expose:
      - 443
   networks:
   default:
      ipv4_address: 172.18.0.30
   volumes:
      - /mnt/fs_docker/mocks/cas.yml:/var/www/app/casino_app/config/cas.yml

Obs: Nesse exemplo existem configurações que necessitam estar disponíveis anteriormente, como a rede.


Anexo: Exemplos de comando em Docker

# Listar todos os containers em execução
$ sudo docker container ps
# Parar a execução do container
$ sudo docker container stop mock-casino-container
# Remover um container
$ sudo docker container rm mock-casino-container
# Executa o container e define que sempre será reiniciado, a menos que que seja parado
$ sudo docker container run --restart=unless-stopped mock-casino-container

Anexo: Laravel Dusk (Básico)

1. Instalando

Dentro do projeto Laravel você deve incluir o componente do Laravel Dusk7)

# diretórios antes
tests
├── CreatesApplication.php
├── Feature
│   └── ExampleTest.php
├── TestCase.php
└── Unit
    └── ExampleTest.php
$ composer require --dev laravel/dusk
$ php artisan dusk:install
# diretórios depois
tests
├── Browser
│   ├── Components
│   ├── console
│   ├── ExampleTest.php
│   ├── Pages
│   │   ├── HomePage.php
│   │   └── Page.php
│   └── screenshots
├── CreatesApplication.php
├── DuskTestCase.php
├── Feature
│   └── ExampleTest.php
├── TestCase.php
└── Unit
    └── ExampleTest.php

2. Configurando

Você precisa criar um arquivo de configuração de ambiente para o dusk na raiz do projeto como .env.dusk que pode ser igual .env dependendo do for precisar somente com o Laravel Dusk.

3. Criando testes

$ php artisan dusk:make T00_Test
# Cria uma classe de teste com o nome solicitado dentro do diretório 
# “tests/Browser” que estende “tests/DuskTestCase.php”
tests/
├── Browser
│   ├── Components
│   ├── console
│   ├── ExampleTest.php
│   ├── Pages
│   │   ├── HomePage.php
│   │   └── Page.php
│   ├── screenshots
│   └── T00_Test.php
├── CreatesApplication.php
├── DuskTestCase.php
├── Feature
│   └── ExampleTest.php
├── TestCase.php
└── Unit
    └── ExampleTest.php

4. Executando

Necessário ter o Chromedriver executando.

# O comando abaixo executa os testes seguindo a ordem alfabética de todos os testes
$ php artisan dusk

É possível executar por grupo de testes adicionando o parâmetro “–group”, que trabalha associado a anotação @group encontrada no comentário de um função ‘test’

$ php artisan dusk --group=T00

Anexo: Chromedriver

Instalando

  1. Baixar a aplicação em http://chromedriver.chromium.org/downloads (Obs: Preferência pela versão 2.*)
  2. Extrair o arquivo ZIP
  3. Disponibilizar o binário extraído como executável no PATH do ambiente (Ex: /usr/local/bin)

Executando

$ /usr/local/bin/chromedriver --whitelisted-ips * &
#
# whitelisted-ips - lista de IPs com conexões permitidas
infotic/projetos/mockcas.txt · Última modificação: 27/04/2021 12:05 por 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki