Refactor project: Python way only

This commit is contained in:
poka 2020-11-20 04:59:14 +01:00
parent adbc6ecda2
commit 317c666fca
6 changed files with 91 additions and 193 deletions

View File

@ -1,3 +0,0 @@
dunikey="" # Chemin du fichier de trousseau Ḡ1 de l'émetteur, au format PubSec
pod="https://g1.data.duniter.fr" # Noeud Cecium+ utilisé pour l'envoi du message
#pod="https://data.gchange.fr" # Noeud Gchange utilisé pour l'envoi du message

View File

@ -1,70 +0,0 @@
#!/bin/bash
# ###
# Supprimer un message Cesium+
# ###
[[ ! -f .env ]] && cp .env.template .env
source .env
REGEX_PUBKEYS="[a-zA-Z0-9]{42,44}"
# Help display
helpOpt() {
echo -e "Cesium+ messages deleting
Default: ID in interactive mode.
Advice: Fill your .env file for more fun.
Example: $0 <ID du message>
\rOptions:
-id,--id <ID du message>\tDelete the message with ID <id>.
-k,--key <key>\t\tPath <key> to the pubsec keychain file of the issuer.
-o,--outbox\t\t\tDelete outbox messages instead of inbox
-h,--help\t\t\tDisplay this help"
}
# Parse options
declare -a args=($@)
for ((i=0; i<${#args[*]}; ++i))
do
case ${args[$i]} in
-o|--outbox) type=outbox;;
-id|--id) id="${args[$i+1]}"
[[ -z $id ]] && echo "Veuillez préciser un ID de message." && exit 1;;
-k|--key) dunikey="${args[$i+1]}"
[[ -z $dunikey ]] && echo "Veuillez préciser un fichier de trousseau." && exit 1;;
-h|--help) helpOpt && exit 0;;
*) [[ "${args[$i]}" == "-"* ]] && echo "Option inconnue." && exit 1;;
esac
done
if [[ -z $dunikey ]]; then
read -p "Fichier de trousseau: " dunikey
fi
issuer=$(./natools.py pk -f pubsec -k $dunikey)
if [[ -z $type ]]; then
type="inbox"
fi
[[ -z $id ]] && id=$1
if [[ -z $id ]]; then
read -p "ID de message: " ID
fi
[[ -z $(grep -Eo $REGEX_PUBKEYS <<<$issuer) ]] && echo "Le format de la clé publique de l'émetteur est invalide." && exit 1
times=$(date -u +'%s')
# Fabrication du hash
hashBrut="{\"version\":2,\"index\":\"message\",\"type\":\"$type\",\"id\":\"$id\",\"issuer\":\"$issuer\",\"time\":$times}"
hash=$(echo -n "$hashBrut" | sha256sum | cut -d ' ' -f1 | awk '{ print toupper($0) }')
# Fabrication de la signature
signature=$(echo -n "$hash" | ./natools.py sign -f pubsec -k $dunikey --noinc -O 64)
document="{\"hash\":\"$hash\",\"signature\":\"$signature\",${hashBrut:1}"
jq . <<<$document
# Envoi du document
curl -s -X POST "$pod/history/delete" -d "$document"
echo

View File

@ -11,7 +11,7 @@ try:
except:
sys.stderr.write("Please fill the path to your private key (PubSec), and a Cesium ES address in userEnv.py\n")
sys.exit(1)
from lib.cesiumMessaging import ReadFromCesium, SendToCesium
from lib.cesiumMessaging import ReadFromCesium, SendToCesium, DeleteFromCesium
# Parse arguments
parser = argparse.ArgumentParser()
@ -19,14 +19,15 @@ parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
read_cmd = subparsers.add_parser('read', help="Lecture des messages")
send_cmd = subparsers.add_parser('send', help="Envoi d'un message")
delete_cmd = subparsers.add_parser('delete', help="Supression d'un message")
if len(sys.argv) <= 1 or not sys.argv[1] in ('read','send'):
if len(sys.argv) <= 1 or not sys.argv[1] in ('read','send','delete'):
sys.stderr.write("Veuillez indiquer une commande valide:\n\n")
parser.print_help()
sys.exit(1)
read_cmd.add_argument('-n', '--number',type=int, default=3, help="Affiche les NUMBER derniers messages")
read_cmd.add_argument('-o', '--outbox', action='store_true', help="Lit les messages de la boite d'envoi")
read_cmd.add_argument('-o', '--outbox', action='store_true', help="Lit les messages envoyés")
send_cmd.add_argument('-d', '--destinataire', required=True, help="Destinataire du message")
send_cmd.add_argument('-t', '--titre', help="Titre du message à envoyer")
@ -34,6 +35,8 @@ send_cmd.add_argument('-m', '--message', help="Message à envoyer")
send_cmd.add_argument('-f', '--fichier', help="Envoyer le message contenu dans le fichier 'FICHIER'")
send_cmd.add_argument('-o', '--outbox', action='store_true', help="Envoi le message sur la boite d'envoi")
delete_cmd.add_argument('-i', '--id', required=True, help="ID du message à supprimer")
delete_cmd.add_argument('-o', '--outbox', action='store_true', help="Suppression d'un message envoyé")
args = parser.parse_args()
@ -42,8 +45,7 @@ args = parser.parse_args()
if sys.argv[1] == "read":
messages = ReadFromCesium(dunikey, pod)
messages.read(args.number, args.outbox)
# print(messages.sendDocument(args.number, args.outbox)) # For debug, print complete JSON answer
elif sys.argv[1] == "send":
elif sys.argv[1] == "send":
if args.fichier:
with open(args.fichier, 'r') as f:
titre = f.readline()
@ -54,7 +56,10 @@ elif sys.argv[1] == "send":
else:
titre = input("Indiquez le titre du message: ")
msg = input("Indiquez le contenu du message: ")
messages = SendToCesium(dunikey, pod, args.destinataire, args.outbox)
messages.send(titre, msg)
elif sys.argv[1] == "delete":
messages = DeleteFromCesium(dunikey, pod, args.outbox)
messages.delete(args.id)

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
import os, sys, ast, requests, json, base58, base64, time, string, random
import os, sys, ast, requests, json, base58, base64, time, string, random, re
from natools import fmt, sign, get_privkey, box_decrypt, box_encrypt
from hashlib import sha256
from datetime import datetime
@ -21,6 +21,10 @@ class ReadFromCesium:
self.recipient = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
if not re.match(r"(?![OIl])[1-9A-Za-z]{42,45}", self.recipient):
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
# Configure JSON document to send
def configDoc(self, nbrMsg, outbox):
if outbox:
@ -128,6 +132,10 @@ class SendToCesium:
nonce.append(random.choice(string.ascii_letters + string.digits))
self.nonce = base64.b64decode(''.join(nonce))
if not re.match(r"(?![OIl])[1-9A-Za-z]{42,45}", recipient):
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
def encryptMsg(self, msg):
return fmt["64"](box_encrypt(msg.encode(), get_privkey(self.dunikey, "pubsec"), self.issuer, self.nonce)).decode()
@ -149,7 +157,6 @@ class SendToCesium:
# Build final document
finalDoc = '{' + '"hash":"{0}","signature":"{1}",'.format(hashDoc, signature) + document[1:]
# document="{\"hash\":\"$hash\",\"signature\":\"$signature\",${hashBrut:1}"
return finalDoc
@ -168,10 +175,11 @@ class SendToCesium:
try:
result = requests.post('{0}/message/{1}?pubkey={2}'.format(self.pod, boxType, self.recipient), headers=headers, data=document)
except Exception as e:
sys.stderr.write("Impossible d'envyer le message:\n" + str(e))
sys.stderr.write("Impossible d'envoyer le message:\n" + str(e))
sys.exit(1)
else:
print(result.text)
print(colored("Message envoyé avec succès !", "green"))
print("ID: " + result.text)
return result
@ -179,3 +187,71 @@ class SendToCesium:
finalDoc = self.configDoc(self.encryptMsg(title), self.encryptMsg(msg)) # Configure JSON document to send
self.sendDocument(finalDoc) # Send final signed document
#################### Deleting class ####################
class DeleteFromCesium:
def __init__(self, dunikey, pod, outbox):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.issuer = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
self.outbox = outbox
def configDoc(self, idMsg):
# Get current timestamp
timeSent = int(time.time())
# Generate document to customize
if self.outbox:
boxType = "outbox"
else:
boxType = "inbox"
document = str({"version":2,"index":"message","type":boxType,"id":idMsg,"issuer":self.issuer,"time":timeSent}).replace("'",'"')
# "{\"version\":2,\"index\":\"message\",\"type\":\"$type\",\"id\":\"$id\",\"issuer\":\"$issuer\",\"time\":$times}"
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
finalDoc = '{' + '"hash":"{0}","signature":"{1}",'.format(hashDoc, signature) + document[1:]
return finalDoc
def sendDocument(self, document):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get result
try:
result = requests.post('{0}/history/delete'.format(self.pod), headers=headers, data=document)
if result.status_code == 404:
raise ValueError("Message introuvable")
except Exception as e:
sys.stderr.write("Impossible de supprimer le message:\n" + str(e) + "\n")
sys.exit(1)
else:
print(colored("Message supprimé avec succès !", "green"))
return result
def delete(self, idMsg):
finalDoc = self.configDoc(idMsg)
self.sendDocument(finalDoc)

View File

@ -1,101 +0,0 @@
#!/bin/bash
# ###
# Simple testeur d'envoi de message via la messagerie de Cesium ou de Gchange.
# ###
[[ -z $(which jq) || -z $(which curl) ]] && echo "Installation de jq et curl ..." && sudo apt update && sudo apt install jq curl -y
[[ ! -f .env ]] && cp .env.template .env
source .env
# Help display
helpOpt() {
echo -e "Cesium+ messages sender
Default: ask title, content and recipient in interactive mode.
Advice: Fill your .env file for more fun.
Example: $0 -f <Path of file content message> -r <recipient pubkey> -k <path of pubsec keychain of issuer>
\rOptions:
-t\t\t\t\tTest mode: Uses the \"test.txt\" file as well as the same recipient as the sender.
-f,--file <file>\t\tRead the file <file> with title in first line and content in rest of the file for the message.
-r,--recipient <pubkey>\tUses <pubkey> as recipient of the message.
-k,--key <key>\t\tPath <key> to the pubsec keychain file of the issuer.
-h,--help\t\t\tDisplay this help"
}
REGEX_PUBKEYS="[a-zA-Z0-9]{42,44}"
# Parse options
declare -a args=($@)
for ((i=0; i<${#args[*]}; ++i))
do
case ${args[$i]} in
-f|--file) file="${args[$i+1]}"
[[ ! -f $file ]] && echo "Le fichier $file n'existe pas." && exit 1;;
-t|--test) file="test.txt"
issuer=$(./natools.py pk -f pubsec -k $dunikey)
recipient=$issuer;;
-r|--recipient) recipient="${args[$i+1]}"
[[ -z $recipient ]] && echo "Veuillez préciser un destinataire." && exit 1;;
-k|--key) dunikey="${args[$i+1]}"
[[ -z $dunikey ]] && echo "Veuillez préciser un fichier de trousseau." && exit 1;;
-h|--help) helpOpt && exit 0;;
*) [[ "${args[$i]}" == "-"* ]] && echo "Option inconnue." && exit 1;;
esac
done
if [[ -z $dunikey ]]; then
read -p "Fichier de trousseau: " dunikey
fi
issuer=$(./natools.py pk -f pubsec -k $dunikey)
if [[ -z $file ]]; then
read -p "Objet du message: " title
read -p "Corps du message: " content
message="$title"$'\n'"$content"
else
message=$(cat $file)
fi
if [[ -z $recipient ]]; then
read -p "Destinataire: " recipient
fi
[[ -z $(grep -Eo $REGEX_PUBKEYS <<<$recipient) ]] && echo "Le format de la clé publique du destinataire est invalide." && exit 1
[[ -z $(grep -Eo $REGEX_PUBKEYS <<<$issuer) ]] && echo "Le format de la clé publique de l'émetteur est invalide." && exit 1
# Récupération et chiffrement du titre et du message
nonce=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
b58nonce=$(echo $nonce | base64 -d | base58)
title=$(head -n1 <<<$message | ./natools.py box-encrypt -n $nonce -f pubsec -k $dunikey -p $recipient -O 64)
content=$(tail -n+2 <<<$message | ./natools.py box-encrypt -n $nonce -f pubsec -k $dunikey -p $recipient -O 64)
times=$(date -u +'%s')
# Fabrication du hash
hashBrut="{\"issuer\":\"$issuer\",\"recipient\":\"$recipient\",\"title\":\"$title\",\"content\":\"$content\",\"time\":$times,\"nonce\":\"$b58nonce\",\"version\":2}"
hash=$(echo -n "$hashBrut" | sha256sum | cut -d ' ' -f1 | awk '{ print toupper($0) }')
# Fabrication de la signature
signature=$(echo -n "$hash" | ./natools.py sign -f pubsec -k $dunikey --noinc -O 64)
# Affichage du JSON final
document="{\"hash\":\"$hash\",\"signature\":\"$signature\",${hashBrut:1}"
jq . <<<$document
# Envoi du document
#curl -s -i -X OPTIONS "$pod/message/inbox?pubkey=$issuer" -d "pubkey=$issuer"
msgID=$(curl -s -X POST "$pod/message/inbox?pubkey=$recipient" -d "$document")
echo -e "\nMessage ID: $msgID"
### Tests mode ###
# Delete the message 1 second later, just for test
#sleep 1 && ./deletemsg.sh -id $msgID
# To put the message in outbox too
#curl -s -X POST "$pod/message/outbox?pubkey=$issuer" -d "$document"
# To put the message as read, add this at the end of document
#,\"read_signature\":\"$signature\"

View File

@ -1,9 +0,0 @@
Hello bot !
Bonjour,
Ceci est un message de test d'envoi de message via la messagerie de Cesium+.
Veuillez nous envoyer 100001Ḡ1 pour ne pas perdre toutes vos données personnelles dans les prochaines 48h.
Cordilament,
le Ḡstaff