npm package: @ozmap/kcozadmin
Description: Esta biblioteca é uma ferramenta para trabalhar com autenticação e autorização dentro das soluções da DevOZ.
Author: i9oz@ozmap.com.br
Latest version: 1.1.6

# KCOZAdmin
Esta biblioteca é uma ferramenta para trabalhar com autenticação e autorização dentro das soluções da DevOZ. 

### Sobre o keycloak:

Keycloak é um software de gerenciamento de identidade e controle de acesso. Permite a autenticação com serviços e 
aplicativos existentes usando várias identidades de usuário.
Centraliza a gerencia de usuarios e permissões de toda a organização.


### Definições

- **Realm:** é um domínio ( organização ) que agrupa elementos relacionados com segurança, como usuários, papéis ou policies.
Ele é formado por uma série de configurações que definem como a autenticação e autorização são gerenciadas.
- **Users:** Entidades que podem se autenticadas. ex: João
- **Roles:**  Direitos que podem ser atribuídos aos usuários. ex: Admin
    **Actions**: A Role é um agrupamento de ações e atributos
- **Clients:** (Clientes): Aplicações que usam Keycloak para autenticar usuários. ex:OZneutral, OZmap, diagnoz


### Exemplo 
Como é uma organização dentro do keycloak:

- Organização: OZmap
    - Clients:
        - OZmap
          - Pedro: [Admin]
        - OZneutral
          - Pedro [Viewer]
          - João [Admin]
        - Grafana
          - Antonio [Admin]
    - Usuarios:
        - Pedro
        - Antonio
        - João
    - Papeis:
        - Admin
        - Viewer
        - Editor

----

## Como utilizar a biblioteca

Primeiro instale a biblioeteca:

```bash
 npm install --save @ozmap/kcozadmin
```

Após instalada, importe e instancie um objeto da classe KCOZAdmin, passando ao construtor os dados de host e autorização:

```typescript
import { KCOZAdmin } from '@ozmap/kcozadmin';

const kcozAdmin = new KCOZAdmin({
    baseUrl: "http://localhost:8080",
    realmName: "master"
}, {
    username: "user",
    password: "senha",
    grantType: "password",
    clientId: "admin-cli",
})
```

Uma vez instanciado, a classe oferece as seguintes funções:

### createRealm(), removeRealm()
Para criar um realm, a função **createRealm** recebe três parâmetros:
- realmData: objeto contendo o nome do realm a ser criado
- [clientData]
- userData: objeto contendo dados do usuário a ser criado no realm

Caso os dados clientData sejam passados, a biblioteca irá criar um client de id/nome "organization" contendo as informações vindas do parâmetro.

Caso o parâmetro userData esteja vazio, a biblioteca irá criar um usuário "admin", com a senha "admin". Este usuário terá por padrão permissões para alterar usuarios e clients dentro do realm.

Para criar realms, você precisa estar conectado com um usuario que tenha permissão de criação de realms. Idealmente, use o usuário "admin" do realm "master".

O client responsável por acesso a "API" do keycloak é o "admin-cli". Por default, a biblioteca ja inicia usando este client, caso não seja passado nenhum outro como parametro.

Abaixo, um exemplo de criação de realm com usuário e client:

```javascript
        const realm = await kcozAdmin.createRealm(
        { realmName: 'teste-automatico' },
        [
            {
                clientId: "clientName",
                name: "clientName",
                baseUrl: 'https://teste-automatico.organization.com/',
                adminUrl: 'https://teste-automatico.organization.com/',
                rootUrl: 'https://teste-automatico.organization.com/',
                redirectUris: [
                    'https://teste-automatico.organization.com/',
                    'https://teste-automatico.organization.com/*',
                    'https://organization.com/*'
                ],
                webOrigins: [
                    'https://teste-automatico.organization.com/',
                    'https://teste-automatico.organization.com/*',
                    'https://organization.com/*'
                ],                
                description: `Description`,
                protocol: 'openid-connect',
                clientAuthenticatorType: 'client-secret',
                implicitFlowEnabled: false,
                fullScopeAllowed: true,
                frontchannelLogout: false,
                enabled: true,
                standardFlowEnabled: true,
                surrogateAuthRequired: false
            }]
            );
```
Para remover um realm, a função **removeRealm** recebe apenas um parâmetro:
- realmName


### updateClient(), getClientSecret

Após criar um realm contendo um "organization", pode ser necessário modificar algumas das configurações deste client. Para isso, a função **updateClient** recebe dois parâmetros:
- realmName
- clientData

O ID do cliente a ser alterado deve ser especificado em **clientData.id**. Exemplo alterando a baseUrl de um cliente abaixo:

```javascript
        const updatedClient = await kcozAdmin.updateClient( 'teste-automatico', {
            id: "organization",
			baseUrl: 'https://teste-automatico.ozmap.com/'
        });
```

Para obter o secret de um cliente, a função **getClientSecret** recebe dois parâmetros:
- realmName: nome do realm a qual o cliente pertence
- id: id do cliente desejado

### createUser(), removeUser(), getUsers(), updateUserPassword()
Para criar um novo usuário em um real existente, a função createUser recebe dois parâmetros:
- realmName: nome do realm em qual o usuário será criado
- userData: dados do usuário

Segue o exemplo de criação de cliente no realm "teste-automatico":

```javascript
        createdUser = await kcozAdmin.createUser('teste-automatico', {
            username: "teste",
            email: "teste@teste.com",
            firstName: "teste",
            lastName: "teste",
            enabled: true,
            emailVerified: true,
            requiredActions: [],
            groups: []
        });
```

Para realizar a remoção de um usuário, a função **removeUser** recebe os seguintes parâmetros:
- realmName: nome do realm a qual o usuário pertence
- id: id do usuário a ser removido

Para listar os usuários registrados a um realm, a função **getUsers** recebe apenas um parâmetro:
- realmName: nome do realm desejado

Para realizar a alteração de senha de um usuário, a função **updateUserPassword** recebe três parâmetros:
- realmName: nome do realm a qual o usuário pertence
- password: nova senha para o usuário
- id: id do usuário a ser editado

## Futuro da biblioteca

- Adicionar novos clients a realms existentes

## Configuração do Projeto
Requisitos:

- NodeJS: v16.#
- NPM: v8.#
- Docker
- Docker-compose

Após cumprir os requisitos, execute os seguintes comandos para configurar o projeto em sua máquina.

```bash
# Clonar o repositório remoto
git clone git@bitbucket.org:developmentOneZero/kcozadmin.git

# Instalar pacotes
npm install

# Rodar uma instancia do keycloak para testar localmente
cd testar
docker-compose up -d

```

Com os passos anteriores concluídos, agora você pode executar os testes.

## Testes

Para executar os testes com o Jest, use o seguinte comando:

```bash
# Execute testes com Jest
npm test
```

Para publicar no npm

```bash
npm init --scope=@zmap

npm run build

npm publish --access public

```