Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DEV_DATABASE_URL=postgresql://dev_user:motdepassedev@51.255.51.83:5433/dev_db
FLASK_ENV="development"
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.env
#.env
migrations/

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -130,7 +131,7 @@ celerybeat.pid
*.sage.py

# Environments
.env
#.env
.venv
env/
venv/
Expand Down
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
FROM python:3.11-slim


COPY requirements.txt .


RUN apt update && apt install -y git && rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . .


CMD ["python","app.py"]


#ENTRYPOINT ["flask"]
#CMD ["run"]
#EXPOSE 5000
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

# Project Management API

### Ce micro-service va nous permettre de gérer tous les autres micro-services en les ajoutant, supprimant, avec un système de validation /refus et en se basant sur le système d'authentification.
###### Ce micro-service va nous permettre de gérer tous les autres micro-services en les ajoutant, supprimant, avec un système de validation /refus et en se basant sur le système d'authentification.

## Arborescense
Voici l'arborescence de notre API, avec en commentaire pour chaque dossier/fichier :
Expand Down
8 changes: 3 additions & 5 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from flask import Flask, jsonify
from app.config import *
from app.extensions import jwt
from app.extensions import jwt, db
import os
from dotenv import load_dotenv


__version__ = "1.0.1" # géré automatiquement par la CI
__version__ = "0.1.1" # géré automatiquement par la CI


load_dotenv(".env")
Expand All @@ -16,10 +15,9 @@ def create_app():
app.config.from_object(config[os.getenv("FLASK_ENV") or "development"])#en mode dev par défaut si rien de spécifié


#db.init_app(app)
db.init_app(app)
jwt.init_app(app)


@jwt.unauthorized_loader # gérer le cas ou le client n'est pas authentifié
def unauthorized_callback(callback):
return jsonify({"msg": "Token invalide ou manquant. veuillez vous authentifier."}), 401
Expand Down
6 changes: 4 additions & 2 deletions app/extensions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager
from depsec_db.extensions import db

db = db

#from depsec_models.database import db

#db= depsec_models.database.db
jwt = JWTManager()
jwt = JWTManager()
145 changes: 67 additions & 78 deletions app/routes/routes1.py
Original file line number Diff line number Diff line change
@@ -1,126 +1,115 @@
from flask import Blueprint, json, request, jsonify
from flask import Blueprint, current_app, json, request, jsonify
from flask_jwt_extended import create_access_token
#from app.extensions import db
from app.extensions import db
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import re
from app.services.auth import verify_token
from flask import current_app
from app.extensions import db
from depsec_db.models import Project
#from depsec_models.models import * #import des modèles depuis le package


projets_bp = Blueprint("projets", __name__)
limiter = Limiter(get_remote_address, default_limits=["5 per minute"])


# ---------- Phase de test avant la BDD (comme si test.json était ce qu'on récupérait de la BDD) ------------- #


projects = [
{
"id":1,
"titre":"Gestion des projets",
"auteur":"Solayman",
"status":"Accept",
"SBOM":"Recup"
},
{
"id":2,
"titre":"Gestion de BDD",
"auteur":"Pierrot la pinto de la mañana",
"status":"Refuse",
"SBOM":"Waiting"
}
]

# ------------------------------------------------------------------------------------------------------------ #

def return_all_proj():
return projects
return Project.query.all()


def return_project(proj):
for p in projects:
for p in return_all_proj():
if proj in p.values():
return p


def add_dico(dico):
def return_project_by_id(id):
return Project.query.get(id)

for d in projects:
if d["titre"] == dico["titre"]:
return jsonify({"error": f"Le nom de projet {d['titre']} existe deja !"}), 400
def add_dico(dico):
projects = return_all_proj()
if projects != []:
for d in projects:
if d.titre == dico["titre"]:
return jsonify({"error": f"Le nom de projet {d.titre} existe deja !"}), 400

# trouve le + grand id
max_id = max([elem['id'] for elem in projects]) if projects else 0
max_id = max([p.id for p in projects]) if projects else 0

dico['id'] = max_id + 1
projects.append(dico)

new_project = Project(
id = dico['id'],
auteur_id=dico["auteur_id"],
titre=dico["titre"],
status=dico["status"],
path=dico["path"]
)

db.session.add(new_project)
db.session.commit()

return return_all_proj()
#save_json(file_path, data)
#return jsonify(load_json(file_path)), 200
return jsonify({"message": f"Projet {new_project.titre} ajoute avec succes"}), 200

def del_dico(id):
global projects
project = return_project_by_id(id)

try:
new_data = [item for item in projects if int(item.get("id")) != int(id)]
except :
return jsonify({"error": "Entrez un entier !"}), 404

if len(new_data) == len(projects):
return jsonify({"error": f"Le projet avec l'id '{id}' n'existe pas !"}), 404
if not project:
return jsonify({"error": f"Projet avec l'ID {id} non trouve"}), 404

db.session.delete(project)
db.session.commit()

projects = new_data
return return_all_proj()
#return jsonify(load_json(file_path)), 200
return jsonify({"message": f"Projet avec l'ID {id} supprime avec succes"}), 200

# ------------------------------------------------------------------------------------------------------------ #


@projets_bp.route('/', methods=['GET'])
def get_projects():
if verify_token() == False and current_app.config["FLASK_ENV"] !="development" : #verifier que le token est valide ( a mettre dans chaque route) et qu'on est pas en environnement de dev
return jsonify({"msg": "Token invalide / Utilisateur non autorisé"}), 401


#data = request.get_json()


return return_all_proj(), 200
#return jsonify({"Projects":data.get('titre')}), 200
return jsonify({"msg": "Token invalide / Utilisateur non autorise"}), 401

return jsonify([project.to_dict() for project in Project.query.all()])

@projets_bp.route('/<int:project_id>', methods=['GET'])
def get_project_by_id(project_id):
project = Project.query.get(project_id)
if not project:
return jsonify({'error': 'Projet non trouvé'}), 404
return jsonify(project.to_dict()), 200

@projets_bp.route('/', methods=['POST'])
def add_project():
if verify_token() == False and current_app.config["FLASK_ENV"] !="development" : #verifier que le token est valide ( a mettre dans chaque route) et qu'on est pas en environnement de dev
return jsonify({"msg": "Token invalide / Utilisateur non autorisé"}), 401

if verify_token() == False and current_app.config["FLASK_ENV"] != "development":
return jsonify({"msg": "Token invalide / Utilisateur non autorise"}), 401

data = request.get_json()

if not data :
return jsonify({"error": "Le fomat de vos donnees n'est pas bon !!"}), 400

if data.get("titre") and data.get("auteur") and data.get("status") and data.get("SBOM"):
titre = data.get("titre")
auteur = data.get("auteur")
status = data.get("status")
sbom = data.get("SBOM")

if isinstance(auteur, str) and status in ["Accept","Refuse"] and sbom in ["Recup","Waiting"]:
format = {
"id":0,
"titre":titre,
"auteur":auteur,
"status":status,
"SBOM":sbom
}
return add_dico(format)
else :
return jsonify({'error': 'Parametres aux mauvais formats !'}), 400
else :
if not data:
return jsonify({"error": "Le format de vos donnees n'est pas bon !!"}), 400

required_fields = ["titre", "auteur_id", "status", "path"]
if not all(field in data for field in required_fields):
return jsonify({'error': 'Parametres manquants'}), 400

titre = data["titre"]
auteur_id = data["auteur_id"]
status = data["status"]
path = data["path"]

if isinstance(auteur_id, int) and status in ["Accept", "Refuse"]:
project_data = {
"auteur_id": auteur_id,
"titre": titre,
"status": status,
"path": path
}
return add_dico(project_data)
else:
return jsonify({'error': 'Parametres aux mauvais formats !'}), 400


@projets_bp.route("/<id>", methods=["DELETE"])
Expand Down
7 changes: 6 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
pip==20.3.4
flask
flask-limiter
Flask-SQLAlchemy
Flask-JWT-Extended
pytest
dotenv
requests
python-semantic-release
python-semantic-release
setuptools
flask_migrate
psycopg2-binary
git+https://github.com/DEPSEC-Project/DB-Management.git@main
3 changes: 1 addition & 2 deletions test/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ def test_inutile():
"""
A modifier si on décide de définir des tests unitaires
"""
assert True

assert True