@desco/sequelize-permission-resources
Version:
System, implemented in Sequelize, allowing users and groups of users to access resources
243 lines (174 loc) • 15.9 kB
Markdown
<div align="right">
<a href="README.US.md">
<img alt="Read in American English" src="https://img.shields.io/static/v1?label=&message=Read+in+American+English&color=red&style=for-the-badge" />
</a>
</div>
<table>
<tr>
<td><img src="https://i.ibb.co/PGLkNY4/sequelize-permission-resources.png"></td>
<td>
<h1>@desco/sequelize-permission-resources</h1>
Pacote que permite controlar o acesso de usuários e grupos de usuários aos recursos do sistema via <a href="https://sequelize.org/" target="_blank">Sequelize.</a>
<br /><br />
<div align="center">
<img alt="Licença MIT" src="https://img.shields.io/static/v1?label=Licen%C3%A7a&message=MIT&color=green&style=for-the-badge">
<img alt="Versão 1.2.5" src="https://img.shields.io/static/v1?label=Vers%C3%A3o&message=1.2.5&color=blue&style=for-the-badge">
</div>
<h4 align="center">
🧪 Em fase Beta 🚀
</h4>
</td>
</tr>
</table>
> <a href="https://github.com/desco-npm" target="_blank">Veja outros projetos NPM aqui.</a>
> <a href="https://github.com/descoifica" target="_blank">Veja outros projetos aqui.</a>
---
## 📋 Tabela de conteúdos
- [✔️ Recursos](#Recursos)
- [🛠️ Tecnologias](#Tecnologias)
- [⚙️ Instalação](#Instalação)
- [📦 Importação](#Importação)
- [📚 Como Usar](#Como-Usar)
---
<a name="Recursos"></a>
## ✔️ Recursos
- [x] Login;
- [x] Login com Google;
- [x] Controle de permissões;
---
## 🛠️ Tecnologias
As seguintes tecnologias são utilizadas:
- [NodeJS](https://nodejs.org/en/);
- [Moment](https://www.npmjs.com/package/moment);
- [Sequelize](https://sequelize.org/);
- [Express](https://expressjs.com/);
---
<a name="Instalação"></a>
## ⚙️ Instalação
```bash
npm install --save @desco/sequelize-permission-resources
```
> Note que será necessário ter o **NPM** instalado para o comando funcionar.
---
<a name="Importação"></a>
## 📦 Importação
```js
const sequelizePermissionResources = require("@desco/sequelize-permission-resources");
```
---
<a name="Como-Usar"></a>
## 📚 Como Usar
### Conceito
Teremos três modelos para armazenar usuários, grupos de usuários e permissões, além de mais um modelo para o relacionamento entre usuários e grupos de usuários.
Os modelos com seus atributos deverão ser criados pelo programador utilizando os nomes que preferir e, uma vez criados, serão informados para o **sequelizePermissionResources** para que possa trabalhar com eles, inclusive criando os relacionamentos.
Uma vez os modelos criados e todos os parâmetros passados ao **sequelizePermissionResources**, tudo será automatizado e serão criadas rotas para login e (no caso do google) callback.
Utilizar o Google por padrão é desabilitado e deve ser habilitado caso deseje utilizar.
Uma vez efetuado o login, um token será retornado para o frontend, o qual deverá ser informado em todas as requisições.
O **sequelizePermissionResources** irá validar o token e, caso valido, irá liberar ou negar o acesso dependendo das permissões dadas ao usuário ou grupo de usuário associado ao token.
Para liberar acesso a um recurso ou URL para todos os usuários, sem necessidade de token, crie um registro no modelo de permissões no qual o acesso será liberado (`true`) e o usuário e grupo de usuário serão `null`.
Falando em liberação ou restrição, três valores são possíveis:
- `true` para liberar;
- `false` para negar;
- `null` para negar a menos que outra permissão esteja liberando;
Como pode ver, é possível ter várias permissões para um recurso ou URL, por exemplo, um usuário pode estar como `null` a uma url e `true` em vários grupos, exceto em um que define como `false`... e agora?
o **sequelizePermissionResources** possui uma hierarquia de importância nas permissões e ela é a seguinte, do menos ao mais importante:
- Permissão Geral (onde usuário e grupo de usuário são `null`);
- Permissão de Grupos;
- Permissão de Usuários;
Dessa forma, se um acesso for negado nas permissões gerais, porém liberado em um dos grupos do usuário, o acesso será liberado pois as permissões de grupos são mais importantes.
Da mesma forma, se o acesso for negado nos grupos, porém liberado diretamente para o usuário, o acesso será liberado pois as permissões de usuário são mais importantes.
Agora, se houver um conflito entre as permissões dos vários grupos, a importância será para a permissão `false`, ou seja, se houver um único grupo com permissão `false` e todos os outros `true`, a permissão será `false`.
Note também que `null` terá comportamento de `false`, mas diferente do `false`, poderá ser sobrescrito pelo `true`.
### Modelos
Comece criando 3 modelos [Sequelize](https://sequelize.org/) com seus atributos, são eles:
> Os nomes dos modelos e atributos não importam pois podem ser personalizados, porém os nomes dos atributos aqui informados servem como padrão.
#### User
Modelo para armazenamento dos usuários, com os seguintes atributos:
- **id** - Id do registro;
- **login** - Nome de login do usuário (String);
- **mail** - Email do usuário (String);
- **password** - Senha do usuário (String);
- **token** - Token do usuário de quando estiver autenticado (Pelo menos 500 caracteres);
- **tokenType** - Tipo do token (Valor ENUM que aceita `default` ou `null`);
- **expireToken** - Data de expiração do token (BIGINT);
#### UserGroup
Modelo para armazenamento dos grupos de usuários, com os seguintes atributos:
- **id** - Id do registro;
- **name** - Nome do grupo (String);
#### User_UserGroup
Modelo que irá relacionar os usuários com os grupos de usuários, com o seguintes atributos:
> O nome deste modelo deve seguir as regras do [Sequelize](https://sequelize.org/) para modelos que relacionam dois outros modelos.
- **id** - Id do registro;
#### Permission
Modelo para armazenamento das permissões de acesso, com os seguintes atributos:
- **id** - Id do registro;
- **resource** - Nome ou URL do recurso (String);
- **allow** - Se o acesso esta liberado (`true`), negado (`false`) ou padrão (`null`);
### Executando
Chame o método passando os devidos parâmetros e a mágica será feita!
```js
sequelizePermissionResources({ ...params });
```
> Veja todos os parâmetros a seguir.
### Parâmetros
| Nome | Tipo | Obrigatório | Padrão | Descrição |
| ------------------ | ------------------------------------------------------------------------------ | ----------- | --------------------------------------- | ------------------------------------------------------------------------- |
| Express | App | Sim | - | Aplicação do Express já declarada |
| Op | [Op](https://sequelize.org/master/manual/model-querying-basics.html#operators) | Sim | - | Objeto de operadores do [Sequelize](https://sequelize.org) |
| User | Objeto | Sim | - | Modelo do [Sequelize](https://sequelize.org) para os Usuários |
| Group | Objeto | Sim | - | Modelo do [Sequelize](https://sequelize.org) para os Grupos de Usuários |
| Permission | Objeto | Sim | - | Modelo do [Sequelize](https://sequelize.org) para as Permissões de Acesso |
| userPkProp | String | Não | 'id' | Nome do atributo de id do modelo de usuário |
| loginProp | String | Não | 'mail' | Nome do atributo de login do modelo de usuário |
| pswProp | String | Não | 'password' | Nome do atributo de senha do modelo de usuário |
| tokenProp | String | Não | 'token' | Nome do atributo de token do modelo de usuário |
| tokenTypeProp | String | Não | 'tokenType' | Nome do atributo de tipo de token do modelo de usuário |
| expireTokenProp | String | Não | 'expireToken' | Nome do atributo de data de expiração do token do modelo de usuário |
| groupPkProp | String | Não | 'id' | Nome do atributo de id do modelo de grupo de usuário |
| resourceProp | String | Não | 'resource' | Nome do atributo de recurso a ser acessado do modelo de permissão |
| allowProp | String | Não | 'allow' | Nome do atributo de liberação do recurso do modelo de permissão |
| secret | String | Sim | - | String segredo a ser usada para criar os tokens |
| algorithm | String | Não | HS256 | Técnica de hash a ser usado nos tokens |
| urlLogin | String | Não | /login | URL da rota de login |
| loginCallback | Function | Não | `(p) => p` | Função ao ser executada ao ter sucesso no login |
| expireToken | Function | Não | `() => moment().add(1, 'hours').unix()` | Função que irá gerar a hora unix de expiração do token |
| invalidToken | JSON | Não | { message: 'Invalid Token', } | JSON a ser retornado caso o token informado seja inválido |
| noToken | JSON | Não | { message: 'No Token', } | JSON a ser retornado caso não tenha passado um token |
| expiredToken | JSON | Não | { message: 'Expired Token', } | JSON a ser retornado caso o token tenha expirado |
| invalidPermission | JSON | Não | { message: 'Invalid Permissions', } | JSON a ser retornado caso não tenha permissão para acessar o recurso |
| google | boolean | Não | false | Se irá usar autenticação via aplicação Google |
| googleURL | String | Não | /oauth/google | URL da rota de login do google |
| googleCallbackbURL | String | Não | /oauth/google/callback | URL da rota de callback do login do google |
| googleId | String | Não | - | ID da aplicação Google |
| googleKey | String | Não | - | Chave da aplicação Google |
| googleScope | String | Não | - | Escopos a serem acessados na aplicação Google |
---
## Autor
<table>
<tr>
<td width="150px">
<img src="https://scontent.fsdu1-1.fna.fbcdn.net/v/t1.0-9/539886_235546170253505_5977326689811409130_n.jpg?_nc_cat=106&ccb=3&_nc_sid=174925&_nc_eui2=AeGgFWn_fWInwRkTo3mHSP993TbQ0TzG0Y3dNtDRPMbRjS-eZL1tr4I5maqz6O-jva9qWnIxKOsD3UtSm9CTeCys&_nc_ohc=Qw6NaDGrtIgAX9uFF2c&_nc_ht=scontent.fsdu1-1.fna&oh=5ebac9874d7a24e157c8c99fd965c2a4&oe=606539CE" width="100px;" alt=""/>
<b>Rafael A. R. Dias</b>
</td>
<td>
<a href="mailto:eu@diasrafael.com.br" target="_blank" >
<img alt="Email eu@diasrafael.com.br" src="https://img.shields.io/static/v1?label=Email&message=eu@diasrafael.com.br&color=red&logo=gmail&style=for-the-badge">
</a>
<a href="https://www.linkedin.com/in/diasrafael/" target="_blank">
<img alt="Linkedin @diasrafael" src="https://img.shields.io/static/v1?label=Linkedin&message=@diasrafael&color=blue&logo=linkedin&style=for-the-badge">
</a>
<a href="https://www.facebook.com/eudiasrafael" target="_blank">
<img alt="Facebook @eudiasrafael" src="https://img.shields.io/static/v1?label=Facebook&message=@eudiasrafael&color=blue&logo=facebook&style=for-the-badge">
</a>
<a href="https://github.com/descodifica" target="_blank">
<img alt="GitHub Geral @descodifica" src="https://img.shields.io/static/v1?label=GitHub+Geral&message=@descodifica&color=black&logo=github&style=for-the-badge">
</a>
<a href="https://github.com/desco-npm" target="_blank">
<img alt="GitHub NPM @desco-npm" src="https://img.shields.io/static/v1?label=GitHub+NPM&message=@desco-npm&color=black&logo=github&style=for-the-badge">
</a>
<a href="https://www.npmjs.com/org/desco" target="_blank">
<img alt="NPM @desco" src="https://img.shields.io/static/v1?label=NPM&message=@desco&color=red&logo=npm&style=for-the-badge">
</a>
</td>
</tr>
</table>