Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blueprints e JWT #8

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2157d32
Merge pull request #2 from danielveigasilva/master
thalleskoester Feb 14, 2020
6a3be94
Add initial modular structure
thalleskoester Feb 14, 2020
e237d5d
Add first part of Application Factory
thalleskoester Feb 14, 2020
91ca432
Add auth routes
thalleskoester Feb 14, 2020
3e4b5de
Add profile routes
thalleskoester Feb 14, 2020
45b4b33
Add report routes
thalleskoester Feb 14, 2020
f49b0a4
Add schedule routes
thalleskoester Feb 14, 2020
efd4d7c
Register blueprints
thalleskoester Feb 14, 2020
016a093
Add auth controller
thalleskoester Feb 14, 2020
53b99f0
Update route handle function
thalleskoester Feb 14, 2020
4341453
Add helpers
thalleskoester Feb 14, 2020
dc805ef
Add profile controller
thalleskoester Feb 14, 2020
829562e
Update router handle function name
thalleskoester Feb 14, 2020
7d52589
Update reports handle function name
thalleskoester Feb 14, 2020
a242ad3
Add reports controller
thalleskoester Feb 14, 2020
d5664f1
Update schedule handle function name
thalleskoester Feb 14, 2020
515a961
Add schedule controller
thalleskoester Feb 14, 2020
cf287cf
Add http error handler
thalleskoester Feb 14, 2020
6c6f0de
Add new entry point
thalleskoester Feb 14, 2020
dfe4673
Update blueprint name
thalleskoester Feb 14, 2020
fca8477
Generating JWT token
thalleskoester Feb 14, 2020
64ef905
Verify token
thalleskoester Feb 14, 2020
d53a942
Start using new http error handler
thalleskoester Feb 14, 2020
c425a4f
Update doc
thalleskoester Feb 14, 2020
9123f98
Update heroku entry point
thalleskoester Feb 14, 2020
d59dc47
Authentication by post
thalleskoester Feb 14, 2020
30d8f42
Update auth route
thalleskoester Feb 14, 2020
25ae4cd
Update doc
thalleskoester Feb 14, 2020
2883cb8
Update doc
thalleskoester Feb 14, 2020
34f809f
Update doc
thalleskoester Feb 14, 2020
eae9344
Update Flask version
thalleskoester Feb 14, 2020
df2e6ec
Changing back to production
thalleskoester Feb 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: python APIPortalCEFET.py
web: python wsgi.py
166 changes: 94 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
<p align="center">
<img src="/imagens/logo.PNG" width="80%">
<br></br>
API desenvolvida em linguagem Python para interação web com o portal online da instituição federal Centro Federal de Educação Tecnológica Celso Suckow da Fonseca (CEFET/RJ).
API desenvolvida em linguagem Python para interação web com o portal online da
nstituição federal Centro Federal de Educação Tecnológica Celso Suckow da Fonseca (CEFET/RJ).
</p>


## Sobre

Application Programming Interface (API) é um conjunto de padrões de programação que permite acesso a um serviço em expecífico. Em resumo, é uma camada intermediária que promove a interação de uma aplicação com o serviço desejado, neste caso o [portal do aluno CEFET/RJ](https://alunos.cefet-rj.br/aluno/).
Application Programming Interface (API) é um conjunto de padrões de programação que
permite acesso a um serviço em expecífico. Em resumo, é uma camada intermediária que
promove a interação de uma aplicação com o serviço desejado, neste caso o
[portal do aluno CEFET/RJ](https://alunos.cefet-rj.br/aluno/).

<p align="center">
<img src="/imagens/api.png" width="80%">
</p>

## Objetivo

Este projeto tem por objetivo fomentar o desenvolvimento de aplicações que visam facilitar o acesso a informações referentes ao portal online de docentes e dicentes da instituição.
Este projeto tem por objetivo fomentar o desenvolvimento de aplicações que visam facilitar
o acesso a informações referentes ao portal online de docentes e dicentes da instituição.

## Desenvolvimento

Este projeto ainda está em desenvolvimento, novas funcionalidades estão sendo adicionadas constantemente. Abaixo segue o andamento das implementações:
Este projeto ainda está em desenvolvimento, novas funcionalidades estão sendo adicionadas constantemente.
Abaixo segue o andamento das implementações:
- **Autenticação**

:heavy_check_mark: autenticacao **[Atualizada** :triangular_flag_on_post: **]**
Expand All @@ -38,86 +44,56 @@ Este projeto ainda está em desenvolvimento, novas funcionalidades estão sendo

## Utilização

Atualmente a API está hospedada no site [Heroku](https://www.heroku.com/) e pode ser acessada através da URL: [https://api-portal-cefet.herokuapp.com/](https://api-portal-cefet.herokuapp.com/).
Atualmente a API está hospedada no site [Heroku](https://www.heroku.com/) e pode ser acessada através da URL:

```url
https://api-portal-cefet.herokuapp.com
```

### Funções

1. **Autenticação**
- **autenticacao (usuario , senha) [POST]**
- **/auth** _[ POST ]_

Esta função é responsável por autenticar uma nova sessão no portal. Deve seguir o padrão abaixo para sua execução:
Esta função é responsável por autenticar uma nova sessão no portal.
O conteudo da sessão devera ser um json contendo a matricula e a senha
no seguinte formato:

URL:
```url
https://api-portal-cefet.herokuapp.com/autenticacao
```

Json:
```json
{
"usuario" : "SUA_MATRICULA_AQUI",
"senha" : "SUA_SENHA_AQUI"
}
```
Se o login occorer corretamente o retorno será um json contendo um *Cookie* e uma *Matrícula* interna do site (**Atenção: a matrícula retornada não está ligada a matrícula acadêmica, se trata de um novo dado usado internamente pelo portal**).

Exemplo de json de retorno:
```json
{
"code": 200,
"data":{
"cookie":"B60E98A57D71D7BBEB80457A125436478",
"matricula":"123456"
}
"usuario" : "%MATRICULA%",
"senha" : "%SENHA%"
}
```

2. **Relatórios**

- **listaRelatorios (cookie , matricula)**

Esta função é responsável por listar os relatórios disponíveis para o seu perfil. Deve seguir o padrão abaixo para sua execução:
```url
https://api-portal-cefet.herokuapp.com/relatorios?cookie=COOKIE_AUTENTICADO_AQUI&matricula=MATRICULA_INTERNA_AQUI

```bash
curl -XPOST -H "Content-type: application/json" -d '{"usuario" : "%MATRICULA%", "senha" : "%SENHA%"}' 'https://api-portal-cefet.herokuapp.com/auth'
```
Se o cookie e a matrícula forem válidos o retorno será um json contendo o código 200 e uma lista de relatórios contendo *ID*, *Nome* e *Link*.

Se o login occorer corretamente o retorno será um json contendo um *token* de autenticação.

Exemplo de json de retorno:
```json
{
"codigo": 200,
"data":[
{
"id":0,
"link":"atestadoTrancamento.action?matricula=123456",
"nome":"Atestado Trancamento"
},
{
"id":1,
"link":"boletimEscolar.action?matricula=123456",
"nome":"Boletim Escolar"
}
]
"code": 200,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6Im9jdCJ9.eyJjb29raWUiOiJjb29raWUtdGVzdGUiLCJtYXRyaWN1bGEiOiIxMjM0NTY3R0NPTSJ9.gq7p3CgzqJyb_MTM30zCkI0K9dEJY4BrGV9d43l9uvw"
}
}
```

- **geraRelatorio (cookie , link)**

Esta função é responsável por gerar um relatório expecificado pelo link (item passado pela função listaRelatorios). Deve seguir o padrão abaixo para sua execução:
```url
https://api-portal-cefet.herokuapp.com/relatorios/pdf?cookie=COOKIE_AUTENTICADO_AQUI&link=LINK_RELATORIO_AQUI
```
Se o cookie e o link forem válidos o retorno será um arquivo *relatorio.pdf*.
2. **Perfil**

3. **Perfil**

- **perfilDados (cookie , matricula)**
- **/perfil** _[ GET ]_

Esta função é responsável por listar os dados principais (*Nome, Curso, Matrícula Acadêmica e Período*). Deve seguir o padrão abaixo para sua execução:
```url
https://api-portal-cefet.herokuapp.com/perfil?cookie=COOKIE_AUTENTICADO_AQUI&matricula=MATRICULA_INTERNA_AQUI
Esta função é responsável por listar os dados principais
(*Nome, Curso, Matrícula Acadêmica e Período*).

```bash
curl -XGET -H 'X-Token: {token}' 'https://api-portal-cefet.herokuapp.com/perfil'
```
Se o cookie e a matrícula forem válidos o retorno será um json contendo o código 200 e uma lista de dados.
Se o token for válido o retorno será um json contendo
o código 200 e uma lista de dados.

Exemplo de json de retorno:

Expand All @@ -133,13 +109,17 @@ Atualmente a API está hospedada no site [Heroku](https://www.heroku.com/) e pod
}
```

- **perfilDadosGerais (cookie , matricula)** *[BETA]*
- **/perfil/geral** _[ GET ] [BETA]_

Esta função é responsável por listar os dados cadastrados, tais como *endereço*, *número de telefone*, *E-mail* e etc. Deve seguir o padrão abaixo para sua execução:
Esta função é responsável por listar os dados cadastrados,
tais como *endereço*, *número de telefone*, *E-mail* e etc.

```url
https://api-portal-cefet.herokuapp.com/perfil/geral?cookie=COOKIE_AUTENTICADO_AQUI&matricula=MATRICULA_INTERNA_AQUI
curl -XGET -H 'X-Token: {token}' 'https://api-portal-cefet.herokuapp.com/perfil/geral'
```
Se o cookie e a matrícula forem válidos o retorno será um json contendo o código 200 e uma lista de dados divididos em quadro tipos: *academico*, *informacoes*, *endereco* e *documentos*.
Se o token for válido o retorno será um json contendo o
código 200 e uma lista de dados divididos em quadro tipos:
*academico*, *informacoes*, *endereco* e *documentos*.

Exemplo de json de retorno:

Expand Down Expand Up @@ -167,12 +147,54 @@ Atualmente a API está hospedada no site [Heroku](https://www.heroku.com/) e pod
}
```

- **perfilFoto (cookie)**
- **/perfil/foto** _[ GET ]_

Esta função é responsável por obter a foto de perfil cadastrada no portal. Deve seguir o padrão abaixo para sua execução:
```url
https://api-portal-cefet.herokuapp.com/perfil/foto?cookie=COOKIE_AUTENTICADO_AQUI
Esta função é responsável por obter a foto de perfil cadastrada no portal.

```bash
curl -XGET -H 'X-Token: {token}' 'https://api-portal-cefet.herokuapp.com/perfil/foto'
```
Se o cookie for válido o retorno será um arquivo *imagemPerfil.jpeg*.
Se o token for válido o retorno será um arquivo *imagemPerfil.jpeg*.



3. **Relatórios**

- **/relatorios** _[ GET ]_

Esta função é responsável por listar os relatórios disponíveis para o seu perfil.

```bash
curl -XGET -H 'X-Token: {token}' 'https://api-portal-cefet.herokuapp.com/relatorios'
```
Se o token for válido o retorno será um json contendo o código 200
e uma lista de relatórios contendo *ID*, *Nome* e *Link*.

Exemplo de json de retorno:
```json
{
"codigo": 200,
"data":[
{
"id":0,
"link":"atestadoTrancamento.action?matricula=123456",
"nome":"Atestado Trancamento"
},
{
"id":1,
"link":"boletimEscolar.action?matricula=123456",
"nome":"Boletim Escolar"
}
]
}
```

- **/relatorios/{link}** _[ GET ]_

Esta função é responsável por gerar um relatório expecificado pelo link.

```url
curl -XGET -H 'X-Token: {token}' 'https://api-portal-cefet.herokuapp.com/relatorios/{link}'
```
Se o token for válido o retorno será um arquivo *relatorio.pdf*.

31 changes: 31 additions & 0 deletions apicefet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from flask import Flask, jsonify
from werkzeug.exceptions import HTTPException


def http_exception_handler(error):
return jsonify({
"code": error.code,
"error": error.description
})


def create_app():
app = Flask(__name__)

# Init configs
# Init extensions

with app.app_context():
from apicefet.auth.routes import auth_bp
from apicefet.profile.routes import profile_bp
from apicefet.reports.routes import reports_bp
from apicefet.schedule.routes import schedule_bp

app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(profile_bp, url_prefix='/perfil')
app.register_blueprint(reports_bp, url_prefix='/relatorios')
app.register_blueprint(schedule_bp, url_prefix='/horarios')

app.register_error_handler(HTTPException, http_exception_handler)

return app
35 changes: 35 additions & 0 deletions apicefet/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from itsdangerous import TimedJSONWebSignatureSerializer
from bs4 import BeautifulSoup as bs
from apicefet.helpers import URLS
from flask import jsonify, request
from requests import Session


def auth():
session = Session()
session.headers.update({'referer': URLS['matricula']})
session.get(URLS['aluno_login_action_error'])

user = request.get_json().get('usuario')
passwd = request.get_json().get('senha')

auth_info = {"j_username": user, "j_password": passwd}

site_post = session.post(URLS['security_check'], data=auth_info)
site_post_bs = bs(site_post.content, "html.parser")

matricula = site_post_bs.find("input", id="matricula")["value"]
cookie = session.cookies.get_dict()

jwt = TimedJSONWebSignatureSerializer('%key%', expires_in=10 * 60)
token = jwt.dumps({
"matricula": matricula,
"cookie": cookie['JSESSIONID']
}).decode("utf-8")

return jsonify({
"code": 200,
"data": {
"token": token
}
})
5 changes: 5 additions & 0 deletions apicefet/auth/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from flask import Blueprint
import apicefet.auth as auth

auth_bp = Blueprint('token', __name__)
auth_bp.add_url_rule('', 'user', auth.auth, methods=['POST'])
34 changes: 34 additions & 0 deletions apicefet/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from requests import Session
import unicodedata

URLS = {
'matricula': 'https://alunos.cefet-rj.br/matricula/',
'index_action': 'https://alunos.cefet-rj.br/aluno/index.action',
'foto_action': 'https://alunos.cefet-rj.br/aluno/aluno/foto.action',
'menu_action_matricula': 'https://alunos.cefet-rj.br/aluno/aluno/quadrohorario/menu.action?matricula=',
'perfil_perfil_action': 'https://alunos.cefet-rj.br/aluno/aluno/perfil/perfil.action',
'aluno_relatorio': 'https://alunos.cefet-rj.br/aluno/aluno/relatorio/',
'relatorio_action_matricula': 'https://alunos.cefet-rj.br/aluno/aluno/relatorio/relatorios.action?matricula=',
'aluno_login_action_error': 'https://alunos.cefet-rj.br/aluno/login.action?error=',
'security_check': 'https://alunos.cefet-rj.br/aluno/j_security_check'
}


def normalizacao(texto):
return unicodedata.normalize('NFKD', texto) \
.encode('ASCII', 'ignore').decode('ASCII') \
.replace(' ', '').replace('\n', '') \
.replace('\r', '')


def Autenticado(cookie):
sessao = Session()
sessao.cookies.set("JSESSIONID", cookie)
sessao.headers.update({'referer': URLS['matricula']})

acesso = sessao.get(URLS['index_action'], allow_redirects=False)

if (acesso.status_code == 302):
return False
else:
return True
Loading