feat: Semaine 9
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
@dataclass
|
||||
class User:
|
||||
username: str
|
||||
is_authenticated: bool = False
|
||||
|
||||
def authentication_required(fonction: Callable):
|
||||
def internal_wrapper(user: User):
|
||||
if not user.is_authenticated:
|
||||
return PermissionError(f"L'utilisateur {user.username} n'est pas authentifié.")
|
||||
return fonction(user)
|
||||
return internal_wrapper
|
||||
|
||||
@authentication_required
|
||||
def operation_sensible(user: User):
|
||||
return f"Opération sensible faite par {user.username}."
|
||||
|
||||
alice = User("alice@courriel.fr", True)
|
||||
bob = User("bob@courriel.fr")
|
||||
|
||||
print(operation_sensible(alice))
|
||||
print(operation_sensible(bob))
|
||||
@@ -0,0 +1,13 @@
|
||||
from typing import Callable
|
||||
|
||||
class Decorateur:
|
||||
def __init__(self, fonction: Callable):
|
||||
self.fonction = fonction
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
print(f"Appel de la fonction {self.fonction.__name__}")
|
||||
return self.fonction(*args, **kwargs)
|
||||
|
||||
@Decorateur
|
||||
def addition(a, b):
|
||||
return a + b
|
||||
@@ -0,0 +1,37 @@
|
||||
from typing import Callable
|
||||
import time
|
||||
|
||||
def decorateur(fonction: Callable):
|
||||
def internal_wrapper(*args, **kwargs):
|
||||
print(f"Appel de la fonction {fonction.__name__}")
|
||||
resultat = fonction(*args, **kwargs)
|
||||
print(f"Fin du décorateur")
|
||||
return resultat
|
||||
return internal_wrapper
|
||||
|
||||
def addition(a, b):
|
||||
return a + b
|
||||
|
||||
def salutations(name):
|
||||
return f"Bonjour {name}."
|
||||
|
||||
def multiplication(a, b, c):
|
||||
return a * b * c
|
||||
|
||||
# Décorateur qui calcule le temps d'exécution de n'importe quelle fonction
|
||||
|
||||
def decorateur_temps(fonction: Callable):
|
||||
def internal_wrapper(*args, **kwargs):
|
||||
nonlocal time_total
|
||||
time_start = time.time()
|
||||
|
||||
result = fonction(*args, **kwargs)
|
||||
|
||||
time_duration = time.time() - time_start
|
||||
time_total += time_duration
|
||||
|
||||
print(f"Temps d'exécution : {time_duration} - Total : {time_total}")
|
||||
return result
|
||||
|
||||
time_total = 0
|
||||
return internal_wrapper
|
||||
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
Classe décoratrice qui calcule le temps d'exécution
|
||||
de n'importe quelle fonction et qui l'enregistre
|
||||
dans une DB SQLite
|
||||
=> (fonction_name, execution_time, execution_date)
|
||||
=> Date : YYYY-MM-DD HH:MM:SS
|
||||
|
||||
1. La DB existe ? Oui, Non
|
||||
2. save()
|
||||
"""
|
||||
|
||||
import sqlite3
|
||||
from typing import Callable
|
||||
from time import time, strftime, gmtime, perf_counter
|
||||
|
||||
|
||||
class Decorateur:
|
||||
def __init__(self, fonction: Callable):
|
||||
self.fonction = fonction
|
||||
self.connection = sqlite3.connect("functions.db")
|
||||
|
||||
def create_table(self):
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS exec_stats(
|
||||
function_name TEXT,
|
||||
execution_time REAL,
|
||||
execution_date TEXT
|
||||
)
|
||||
""")
|
||||
self.connection.commit()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
print(f"Appel de la fonction {self.fonction.__name__}")
|
||||
|
||||
start_time = time.perf_counter()
|
||||
resultat = self.fonction(*args, **kwargs)
|
||||
end_time = time.perf_counter()
|
||||
execution_time = end_time - start_time
|
||||
execution_date = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
self.save_to_db(
|
||||
function_name= self.fonction.__name__,
|
||||
execution_time= execution_time,
|
||||
execution_date= execution_date
|
||||
)
|
||||
|
||||
return resultat
|
||||
|
||||
def save_to_db(self, function_name, execution_time, execution_date):
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("""
|
||||
INSERT INTO exec_stats(function_name, execution_time, execution_date)
|
||||
VALUES (?, ?, ?)
|
||||
""", (function_name, execution_time, execution_date))
|
||||
self.connection.commit()
|
||||
|
||||
@Decorateur
|
||||
|
||||
|
||||
def test():
|
||||
return f"Bah ouais quoi."
|
||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
from typing import Callable
|
||||
|
||||
def decorateur(fonction: Callable):
|
||||
print(f"Appel de la fonction {fonction.__name__}")
|
||||
return fonction # où il retourne le résultat de la fonction
|
||||
|
||||
def simple_fonction():
|
||||
print("Hello tout le monde !")
|
||||
|
||||
fonction_decoree = decorateur(simple_fonction)
|
||||
fonction_decoree()
|
||||
@@ -0,0 +1,13 @@
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description= "Outil de salutation")
|
||||
parser.add_argument("nom", help= "Le nom de la personne à saluer")
|
||||
parser.add_argument("--majuscule", action= "store_true", help= "Afficher le message de salutation en majuscules")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
message = f"Bonjour {args.nom}"
|
||||
if args.majuscule:
|
||||
message = message.upper()
|
||||
|
||||
print(message)
|
||||
@@ -0,0 +1,63 @@
|
||||
import argparse
|
||||
import time
|
||||
|
||||
### Générer adresse IP
|
||||
import random
|
||||
import socket
|
||||
import struct
|
||||
|
||||
def ip_address():
|
||||
return socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
|
||||
### Fin du bloc de l'addresse IP
|
||||
|
||||
parser = argparse.ArgumentParser(prog="NetInfo", description= "Outil réseau")
|
||||
parser.add_argument("-v", "--verbose", action="store_true", help="Mode verbeux")
|
||||
subparsers = parser.add_subparsers(dest="commande", help="Commande à exécuter")
|
||||
|
||||
# parent_parser = argparse.ArgumentParser(add_help=False)
|
||||
# parent_parser.add_argument("-v", "--verbose", action="store_true", help="Mode verbeux")
|
||||
|
||||
scan_parser = subparsers.add_parser("scan", help="Scan d'un hôte")
|
||||
scan_parser.add_argument("host", default="192.168.1.1", help="Adresse IP de l'hôte cible")
|
||||
scan_parser.add_argument("-p", "--ports", default=[80], nargs= "+", type= int)
|
||||
|
||||
whois_parser = subparsers.add_parser("whois", help="Ping sur un hôte")
|
||||
whois_parser.add_argument("domain", help="Domaine désiré pour les informations")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
def net_info(fonction):
|
||||
def internal_wrapper(args):
|
||||
if args.verbose:
|
||||
print(f"[DEBUG] Lancement de la commande...")
|
||||
start_time = time.perf_counter()
|
||||
result = fonction(args)
|
||||
print(f"[DEBUG] Commande terminée.")
|
||||
print(f"[DEBUG] Commande exécutée en {time.perf_counter() - start_time} secondes.")
|
||||
return result
|
||||
return fonction(args)
|
||||
return internal_wrapper
|
||||
|
||||
@net_info
|
||||
def scan(args):
|
||||
print(f"Scan de l'hôte: {args.host}")
|
||||
results = []
|
||||
for port in args.ports:
|
||||
status = "ouvert" if port % 2 == 0 else "fermé"
|
||||
results.append(f"Port {port}: {status}")
|
||||
print(f"Port {port}: {status}")
|
||||
return results
|
||||
|
||||
@net_info
|
||||
def whois(args):
|
||||
print(f"WHOIS pour {args.domain}")
|
||||
print(f"\
|
||||
IP : {ip_address()}\n\
|
||||
Registrar : Exemple\n\
|
||||
Expirattion : Bientôt\n\
|
||||
")
|
||||
|
||||
if args.commande == "scan":
|
||||
scan(args)
|
||||
elif args.commande == "whois":
|
||||
whois(args)
|
||||
@@ -0,0 +1,11 @@
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description= "Outil réseau")
|
||||
subparsers = parser.add_subparsers(dest="commande", help="Commande à exécuter")
|
||||
|
||||
scan_parser = subparsers.add_parser("scan", help="Scan d'un hôte")
|
||||
scan_parser.add_argument("--host")
|
||||
scan_parser.add_argument("--port", nargs= "+", type= int)
|
||||
|
||||
ping_parser = subparsers.add_parser("ping", help="Ping sur un hôte")
|
||||
ping_parser.add_argument()
|
||||
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "jour-01"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"typing>=3.10.0.0",
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Callable
|
||||
|
||||
@dataclass
|
||||
class User:
|
||||
username: str
|
||||
is_authenticated: bool = False
|
||||
roles: list[str] = field(default_factory=lambda: ["user"])
|
||||
|
||||
|
||||
def required_roles(roles: list[str]):
|
||||
def wrapper(fonction: Callable):
|
||||
def internal_wrapper(user: User):
|
||||
if not any(role in user.roles for role in roles): # True => [False, False, True]
|
||||
raise PermissionError(f"L'utilisateur {user.username} n'a pas le rôle requis.")
|
||||
return fonction(user)
|
||||
return internal_wrapper
|
||||
return wrapper
|
||||
|
||||
@required_roles(["admin", "modo"])
|
||||
def operation_sensible(user: User):
|
||||
return f"Opération sensible faite par {user.username}"
|
||||
|
||||
alice = User("alice@courriel.fr", True, ["modo"])
|
||||
bob = User("bob@courriel.fr", True)
|
||||
|
||||
print(operation_sensible(alice))
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
uv run scanner.py --host 192.0.0.1 --port 80 -t 2.5
|
||||
-h / --host : hôte en texte
|
||||
-p / --port : port en int
|
||||
-t / --timeout : timeout en secondes (float)
|
||||
"""
|
||||
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(prog="Bistro", description= "Connexion à un serveur distant")
|
||||
|
||||
parser.add_argument("--host", type= str, help= "Défini l'emplacement du serveur")
|
||||
parser.add_argument("-p", "--ports", type= int, choices= [80, 443, 3000, 8000], nargs= "+", default= 80, help= "Défini le port visé sur le serveur")
|
||||
parser.add_argument("-t", "--timeout", type= float, help= "Défini (optionnellement) une durée d'exécution maximum sans retour du serveur avant échec")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
for port in args.ports:
|
||||
print(f"Scan de {args.host} sur le port {port} (timeout= {args.timeout})")
|
||||
Generated
+23
@@ -0,0 +1,23 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "jour-01"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "typing" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "typing", specifier = ">=3.10.0.0" }]
|
||||
|
||||
[[package]]
|
||||
name = "typing"
|
||||
version = "3.10.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b0/1b/835d4431805939d2996f8772aca1d2313a57e8860fec0e48e8e7dfe3a477/typing-3.10.0.0.tar.gz", hash = "sha256:13b4ad211f54ddbf93e5901a9967b1e07720c1d1b78d596ac6a439641aa1b130", size = 78962, upload-time = "2021-05-01T18:03:58.186Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/5d/865e17349564eb1772688d8afc5e3081a5964c640d64d1d2880ebaed002d/typing-3.10.0.0-py3-none-any.whl", hash = "sha256:12fbdfbe7d6cca1a42e485229afcb0b0c8259258cfb919b8a5e2a5c953742f89", size = 26320, upload-time = "2021-05-01T18:03:56.398Z" },
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
import argparse
|
||||
import time
|
||||
|
||||
def timer_command(fonction):
|
||||
def internal_wrapper(args):
|
||||
if args.verbose:
|
||||
print("[DEBUG] Lancement de la commande...")
|
||||
start_time = time.perf_counter()
|
||||
result = fonction(args)
|
||||
print(f"[DEBUG] Terminé en {time.perf_counter() - start_time}")
|
||||
return result
|
||||
return fonction(args)
|
||||
return internal_wrapper
|
||||
|
||||
parser = argparse.ArgumentParser(description="Un scanneur")
|
||||
parser.add_argument("-n", "--numbers", nargs= "+", type= int, help="Nombres à additioner")
|
||||
parser.add_argument("-v", "--verbose", action="store_true", help="Mode verbeux")
|
||||
|
||||
@timer_command
|
||||
def addition(args):
|
||||
return sum(args.numbers)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(addition(args))
|
||||
Reference in New Issue
Block a user