[PD2] Client done except jwt token, login and register functions
This commit is contained in:
parent
c94831d0a2
commit
78031d8e70
16 changed files with 698 additions and 337 deletions
|
@ -3,16 +3,24 @@ package client
|
|||
import (
|
||||
"PD2/internal/protocol"
|
||||
"PD2/internal/utils/cryptoUtils"
|
||||
"PD2/internal/utils/networking"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const baseURL = "https://127.0.0.1:9090"
|
||||
|
||||
func Run() {
|
||||
var userFile string
|
||||
flag.StringVar(&userFile, "user", "userdata.p12", "Specify user data file")
|
||||
|
@ -28,6 +36,8 @@ func Run() {
|
|||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
token = cryptoUtils.GetUserToken()
|
||||
|
||||
command := flag.Arg(0)
|
||||
switch command {
|
||||
case "send":
|
||||
|
@ -65,10 +75,11 @@ func Run() {
|
|||
}
|
||||
}
|
||||
|
||||
err := askQueueCommand(clientKeyStore, page, pageSize)
|
||||
page, pageSize, listClientMessageInfo, err := askQueueCommand(clientKeyStore, page, pageSize)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
showMessagesInfo(page, pageSize, listClientMessageInfo)
|
||||
|
||||
case "getmsg":
|
||||
if flag.NArg() < 2 {
|
||||
|
@ -81,10 +92,11 @@ func Run() {
|
|||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
err = getMsgCommand(clientKeyStore, num)
|
||||
msg, err := getMsgCommand(clientKeyStore, num)
|
||||
if err != nil {
|
||||
printError(err.Error())
|
||||
}
|
||||
showMessage(msg)
|
||||
|
||||
case "help":
|
||||
showHelp()
|
||||
|
@ -96,6 +108,11 @@ func Run() {
|
|||
|
||||
}
|
||||
|
||||
func getHTTPClient(tlsConfig *tls.Config) *http.Client {
|
||||
transport := &http.Transport{TLSClientConfig: tlsConfig}
|
||||
return &http.Client{Transport: transport}
|
||||
}
|
||||
|
||||
func sendCommand(clientKeyStore cryptoUtils.KeyStore, plainSubject, plainBody, uid string) error {
|
||||
//Turn content to bytes
|
||||
plainSubjectBytes, err := Marshal(plainSubject)
|
||||
|
@ -107,18 +124,10 @@ func sendCommand(clientKeyStore cryptoUtils.KeyStore, plainSubject, plainBody, u
|
|||
return err
|
||||
}
|
||||
|
||||
// FIX: adapt to api
|
||||
cl, err := networking.NewClient[protocol.Packet](&clientKeyStore)
|
||||
receiverCert, err := getUserCert(clientKeyStore, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cl.Connection.Conn.Close()
|
||||
|
||||
receiverCert, err := getUserCert(cl, clientKeyStore, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// NOTE: this will stay the same
|
||||
subject, err := clientKeyStore.EncryptMessageContent(receiverCert, uid, plainSubjectBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -128,159 +137,257 @@ func sendCommand(clientKeyStore cryptoUtils.KeyStore, plainSubject, plainBody, u
|
|||
return err
|
||||
}
|
||||
|
||||
// FIX: adapt to api
|
||||
sendMsgPacket := protocol.NewSendMsgPacket(uid, subject, body)
|
||||
if err := cl.Connection.Send(sendMsgPacket); err != nil {
|
||||
return err
|
||||
}
|
||||
answerSendMsg, err := cl.Connection.Receive()
|
||||
client := getHTTPClient(clientKeyStore.GetClientTLSConfig())
|
||||
|
||||
// Parse the base URL
|
||||
parsedURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error parsing URL: %v", err)
|
||||
}
|
||||
if answerSendMsg.Flag == protocol.FlagReportError {
|
||||
reportError, err := protocol.UnmarshalReportError(answerSendMsg.Body)
|
||||
if err != nil {
|
||||
parsedURL.JoinPath("message")
|
||||
|
||||
sendMsgPacket := protocol.NewSendMsg(uid, subject, body)
|
||||
|
||||
jsonData, err := json.Marshal(sendMsgPacket)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshaling JSON: %v", err)
|
||||
}
|
||||
|
||||
//TODO: ADD THE HEADER WITH THE TOKEN
|
||||
req, err := http.NewRequest("POST", parsedURL.String(), bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating request: %v", err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error making request: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read response
|
||||
responseBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading response body: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
var reportError protocol.ReportError
|
||||
if err := json.Unmarshal(responseBody, &reportError); err != nil {
|
||||
return err
|
||||
}
|
||||
return errors.New(reportError.ErrorMessage)
|
||||
}
|
||||
return nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMsgCommand(clientKeyStore cryptoUtils.KeyStore, num int) error {
|
||||
cl, err := networking.NewClient[protocol.Packet](&clientKeyStore)
|
||||
func getMsgCommand(clientKeyStore cryptoUtils.KeyStore, num int) (ClientMessage, error) {
|
||||
|
||||
client := getHTTPClient(clientKeyStore.GetClientTLSConfig())
|
||||
|
||||
// Parse the base URL
|
||||
parsedURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, fmt.Errorf("error parsing URL: %v", err)
|
||||
}
|
||||
defer cl.Connection.Conn.Close()
|
||||
packet := protocol.NewGetMsgPacket(num)
|
||||
if err := cl.Connection.Send(packet); err != nil {
|
||||
return err
|
||||
parsedURL.JoinPath("message")
|
||||
|
||||
newGetMsg := protocol.NewGetMsg(num)
|
||||
|
||||
jsonData, err := json.Marshal(newGetMsg)
|
||||
if err != nil {
|
||||
return ClientMessage{}, fmt.Errorf("error marshaling JSON: %v", err)
|
||||
}
|
||||
|
||||
receivedMsgPacket, err := cl.Connection.Receive()
|
||||
//TODO: ADD THE HEADER WITH THE TOKEN
|
||||
req, err := http.NewRequest("GET", parsedURL.String(), bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, fmt.Errorf("error creating request: %v", err)
|
||||
}
|
||||
if receivedMsgPacket.Flag == protocol.FlagReportError {
|
||||
reportError, err := protocol.UnmarshalReportError(receivedMsgPacket.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return ClientMessage{}, fmt.Errorf("error making request: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read response
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return ClientMessage{}, fmt.Errorf("error reading response body: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
var reportError protocol.ReportError
|
||||
if err := json.Unmarshal(body, &reportError); err != nil {
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
return errors.New(reportError.ErrorMessage)
|
||||
return ClientMessage{}, errors.New(reportError.ErrorMessage)
|
||||
}
|
||||
answerGetMsg, err := protocol.UnmarshalAnswerGetMsg(receivedMsgPacket.Body)
|
||||
|
||||
var answerGetMsg protocol.AnswerGetMsg
|
||||
if err := json.Unmarshal(body, &answerGetMsg); err != nil {
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
|
||||
senderCert, err := getUserCert(clientKeyStore, answerGetMsg.FromUID)
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
senderCert, err := getUserCert(cl, clientKeyStore, answerGetMsg.FromUID)
|
||||
|
||||
oidMap := cryptoUtils.ExtractAllOIDValues(clientKeyStore.GetCert())
|
||||
myUID := oidMap["2.5.4.65"]
|
||||
if myUID == "" {
|
||||
return ClientMessage{}, errors.New("no pseudonym field on my certificate")
|
||||
}
|
||||
|
||||
decSubjectBytes, err := clientKeyStore.DecryptMessageContent(senderCert, myUID, answerGetMsg.Subject)
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
decSubjectBytes, err := clientKeyStore.DecryptMessageContent(senderCert, answerGetMsg.Subject)
|
||||
decBodyBytes, err := clientKeyStore.DecryptMessageContent(senderCert, myUID, answerGetMsg.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
decBodyBytes, err := clientKeyStore.DecryptMessageContent(senderCert, answerGetMsg.Body)
|
||||
messageSubject, err := Unmarshal(decSubjectBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
subject, err := Unmarshal(decSubjectBytes)
|
||||
messageBody, err := Unmarshal(decBodyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
return ClientMessage{}, err
|
||||
}
|
||||
body, err := Unmarshal(decBodyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
message := newClientMessage(answerGetMsg.FromUID, answerGetMsg.ToUID, subject, body, answerGetMsg.Timestamp)
|
||||
showMessage(message)
|
||||
return nil
|
||||
message := newClientMessage(answerGetMsg.FromUID, answerGetMsg.ToUID, messageSubject, messageBody, answerGetMsg.Timestamp)
|
||||
return message, nil
|
||||
}
|
||||
|
||||
func getUserCert(cl networking.Client[protocol.Packet], keyStore cryptoUtils.KeyStore, uid string) (*x509.Certificate, error) {
|
||||
getUserCertPacket := protocol.NewGetUserCertPacket(uid)
|
||||
if err := cl.Connection.Send(getUserCertPacket); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var answerGetUserCertPacket *protocol.Packet
|
||||
answerGetUserCertPacket, err := cl.Connection.Receive()
|
||||
func getUserCert(keyStore cryptoUtils.KeyStore, uid string) (*x509.Certificate, error) {
|
||||
|
||||
client := getHTTPClient(keyStore.GetClientTLSConfig())
|
||||
|
||||
// Parse the base URL
|
||||
parsedURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("error parsing URL: %v", err)
|
||||
}
|
||||
if answerGetUserCertPacket.Flag == protocol.FlagReportError {
|
||||
reportError, err := protocol.UnmarshalReportError(answerGetUserCertPacket.Body)
|
||||
parsedURL.JoinPath("cert")
|
||||
parsedURL.JoinPath(uid)
|
||||
|
||||
//TODO: ADD THE HEADER WITH THE TOKEN
|
||||
req, err := http.NewRequest("GET", parsedURL.String(), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %v", err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read response
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
var answerGetUserCert protocol.AnswerGetUserCert
|
||||
if err := json.Unmarshal(body, &answerGetUserCert); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userCert, err := x509.ParseCertificate(answerGetUserCert.Certificate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := keyStore.CheckCert(userCert, uid, "MSG SERVICE"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userCert, nil
|
||||
} else {
|
||||
var reportError protocol.ReportError
|
||||
if err := json.Unmarshal(body, &reportError); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.New(reportError.ErrorMessage)
|
||||
}
|
||||
answerGetUserCert, err := protocol.UnmarshalAnswerGetUserCert(answerGetUserCertPacket.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userCert, err := x509.ParseCertificate(answerGetUserCert.Certificate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := keyStore.CheckCert(userCert, uid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userCert, nil
|
||||
|
||||
}
|
||||
|
||||
func getManyMessagesInfo(cl networking.Client[protocol.Packet], keyStore cryptoUtils.KeyStore) (protocol.AnswerGetUnreadMsgsInfo, map[string]*x509.Certificate, error) {
|
||||
answerGetUnreadMsgsInfoPacket, err := cl.Connection.Receive()
|
||||
func getUnreadMessagesInfo(keyStore cryptoUtils.KeyStore, page int, pageSize int) (protocol.AnswerGetUnreadMsgsInfo, map[string]*x509.Certificate, error) {
|
||||
client := getHTTPClient(keyStore.GetClientTLSConfig())
|
||||
|
||||
// Parse the base URL
|
||||
parsedURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return protocol.NewAnswerGetUnreadMsgsInfo(0, 0, nil), nil, err
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, fmt.Errorf("error parsing URL: %v", err)
|
||||
}
|
||||
if answerGetUnreadMsgsInfoPacket.Flag == protocol.FlagReportError {
|
||||
reportError, err := protocol.UnmarshalReportError(answerGetUnreadMsgsInfoPacket.Body)
|
||||
if err != nil {
|
||||
parsedURL.JoinPath("queue")
|
||||
|
||||
getUnreadMessagesInfo := protocol.NewGetUnreadMsgsInfo(page, pageSize)
|
||||
|
||||
jsonData, err := json.Marshal(getUnreadMessagesInfo)
|
||||
if err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, fmt.Errorf("error marshaling JSON: %v", err)
|
||||
}
|
||||
|
||||
//TODO: ADD THE HEADER WITH THE TOKEN
|
||||
req, err := http.NewRequest("GET", parsedURL.String(), bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, fmt.Errorf("error creating request: %v", err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, fmt.Errorf("error making request: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Read response
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, fmt.Errorf("error reading response body: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
//Create Set of needed certificates
|
||||
var answerGetUnreadMsgsInfo protocol.AnswerGetUnreadMsgsInfo
|
||||
if err := json.Unmarshal(body, &answerGetUnreadMsgsInfo); err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, err
|
||||
}
|
||||
return protocol.NewAnswerGetUnreadMsgsInfo(0, 0, nil), nil, errors.New(reportError.ErrorMessage)
|
||||
}
|
||||
answerGetUnreadMsgsInfo, err := protocol.UnmarshalAnswerGetUnreadMsgsInfo(answerGetUnreadMsgsInfoPacket.Body)
|
||||
if err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, err
|
||||
}
|
||||
|
||||
//Create Set of needed certificates
|
||||
senderSet := map[string]bool{}
|
||||
for _, messageInfo := range answerGetUnreadMsgsInfo.MessagesInfo {
|
||||
senderSet[messageInfo.FromUID] = true
|
||||
}
|
||||
certificatesMap := map[string]*x509.Certificate{}
|
||||
//Get senders' certificates
|
||||
for senderUID := range senderSet {
|
||||
senderCert, err := getUserCert(cl, keyStore, senderUID)
|
||||
if err == nil {
|
||||
certificatesMap[senderUID] = senderCert
|
||||
senderSet := map[string]bool{}
|
||||
for _, messageInfo := range answerGetUnreadMsgsInfo.MessagesInfo {
|
||||
senderSet[messageInfo.FromUID] = true
|
||||
}
|
||||
|
||||
certificatesMap := map[string]*x509.Certificate{}
|
||||
//Get senders' certificates
|
||||
for senderUID := range senderSet {
|
||||
senderCert, err := getUserCert(keyStore, senderUID)
|
||||
if err == nil {
|
||||
certificatesMap[senderUID] = senderCert
|
||||
}
|
||||
}
|
||||
return answerGetUnreadMsgsInfo, certificatesMap, nil
|
||||
} else {
|
||||
var reportError protocol.ReportError
|
||||
if err := json.Unmarshal(body, &reportError); err != nil {
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, err
|
||||
}
|
||||
return protocol.AnswerGetUnreadMsgsInfo{}, nil, errors.New(reportError.ErrorMessage)
|
||||
|
||||
}
|
||||
return answerGetUnreadMsgsInfo, certificatesMap, nil
|
||||
}
|
||||
|
||||
func askQueueCommand(clientKeyStore cryptoUtils.KeyStore, page int, pageSize int) error {
|
||||
cl, err := networking.NewClient[protocol.Packet](&clientKeyStore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cl.Connection.Conn.Close()
|
||||
return askQueueRec(cl, clientKeyStore, page, pageSize)
|
||||
}
|
||||
func askQueueCommand(clientKeyStore cryptoUtils.KeyStore, page int, pageSize int) (int, int, []ClientMessageInfo, error) {
|
||||
|
||||
func askQueueRec(cl networking.Client[protocol.Packet], clientKeyStore cryptoUtils.KeyStore, page int, pageSize int) error {
|
||||
|
||||
requestUnreadMsgsQueuePacket := protocol.NewGetUnreadMsgsInfoPacket(page, pageSize)
|
||||
if err := cl.Connection.Send(requestUnreadMsgsQueuePacket); err != nil {
|
||||
return err
|
||||
}
|
||||
unreadMsgsInfo, certificates, err := getManyMessagesInfo(cl, clientKeyStore)
|
||||
unreadMsgsInfo, certificates, err := getUnreadMessagesInfo(clientKeyStore, page, pageSize)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
var clientMessages []ClientMessageInfo
|
||||
for _, message := range unreadMsgsInfo.MessagesInfo {
|
||||
|
@ -295,7 +402,12 @@ func askQueueRec(cl networking.Client[protocol.Packet], clientKeyStore cryptoUti
|
|||
clientMessages = append(clientMessages, clientMessageInfo)
|
||||
continue
|
||||
}
|
||||
decryptedSubjectBytes, err := clientKeyStore.DecryptMessageContent(senderCert, message.Subject)
|
||||
oidMap := cryptoUtils.ExtractAllOIDValues(clientKeyStore.GetCert())
|
||||
myUID := oidMap["2.5.4.65"]
|
||||
if myUID == "" {
|
||||
return 0, 0, nil, errors.New("no pseudonym field on my certificate")
|
||||
}
|
||||
decryptedSubjectBytes, err := clientKeyStore.DecryptMessageContent(senderCert, myUID, message.Subject)
|
||||
if err != nil {
|
||||
clientMessageInfo = newClientMessageInfo(message.Num, message.FromUID, "", message.Timestamp, err)
|
||||
clientMessages = append(clientMessages, clientMessageInfo)
|
||||
|
@ -315,13 +427,5 @@ func askQueueRec(cl networking.Client[protocol.Packet], clientKeyStore cryptoUti
|
|||
return clientMessages[i].Num > clientMessages[j].Num
|
||||
})
|
||||
|
||||
action := showMessagesInfo(unreadMsgsInfo.Page, unreadMsgsInfo.NumPages, clientMessages)
|
||||
switch action {
|
||||
case -1:
|
||||
return askQueueRec(cl, clientKeyStore, max(1, unreadMsgsInfo.Page-1), pageSize)
|
||||
case 1:
|
||||
return askQueueRec(cl, clientKeyStore, max(1, unreadMsgsInfo.Page+1), pageSize)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
return unreadMsgsInfo.Page, unreadMsgsInfo.NumPages, clientMessages, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue