meowlib/client/identity.go

135 lines
4.4 KiB
Go
Raw Normal View History

2022-09-06 09:30:45 +02:00
package client
2022-01-15 22:19:29 +01:00
import (
"encoding/json"
"errors"
2022-12-02 23:18:13 +01:00
"os"
2022-01-15 22:19:29 +01:00
2022-09-06 09:30:45 +02:00
"forge.redroom.link/yves/meowlib"
2022-01-15 22:19:29 +01:00
"github.com/ProtonMail/gopenpgp/v2/helper"
"github.com/google/uuid"
2022-01-15 22:19:29 +01:00
)
2021-10-18 21:05:44 +02:00
type Identity struct {
Nickname string `json:"nickname,omitempty"`
RootKp meowlib.KeyPair `json:"id_kp,omitempty"`
Status string `json:"status,omitempty"`
Peers PeerList `json:"peers,omitempty"`
KnownServers InternalServerList `json:"known_servers,omitempty"`
MessageServers InternalServerList `json:"message_servers,omitempty"`
2022-10-29 20:07:35 +02:00
ArchiveServers InternalServerList `json:"archive_servers,omitempty"`
OwnedServers InternalServerList `json:"owned_servers,omitempty"`
DefaultDbPassword string `json:"default_db_password,omitempty"`
DbPasswordStore bool `json:"db_password_store,omitempty"`
2022-10-29 20:07:35 +02:00
OwnedDevices PeerList `json:"owned_devices,omitempty"`
2021-10-18 21:05:44 +02:00
}
2022-01-15 22:19:29 +01:00
func CreateIdentity(nickname string) *Identity {
2021-10-18 21:05:44 +02:00
var id Identity
2022-01-15 22:19:29 +01:00
id.Nickname = nickname
2022-09-06 17:07:35 +02:00
id.RootKp = meowlib.NewKeyPair()
2022-01-15 22:19:29 +01:00
return &id
2021-10-18 21:05:44 +02:00
}
func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerIdxs []int) (*meowlib.ContactCard, error) {
2021-10-18 21:05:44 +02:00
var peer Peer
2022-09-06 09:30:45 +02:00
var myContactCard meowlib.ContactCard
peer.MyIdentity = meowlib.NewKeyPair()
peer.MyEncryptionKp = meowlib.NewKeyPair()
peer.MyLookupKp = meowlib.NewKeyPair()
2022-09-06 17:07:35 +02:00
peer.Name = ContactName
peer.InvitationId = uuid.New().String()
if id.MessageServers.Servers == nil {
2022-11-30 21:35:38 +01:00
return nil, errors.New("no message servers defined in your identity")
}
for _, i := range MessageServerIdxs {
if i > len(id.MessageServers.Servers)-1 {
return nil, errors.New("requested server out of range of defined message servers")
}
}
2022-09-06 17:07:35 +02:00
for _, i := range MessageServerIdxs {
2022-12-03 00:05:28 +01:00
srv := &id.MessageServers.Servers[i].ServerData
myContactCard.PullServers = append(myContactCard.PullServers, srv)
2022-01-15 22:19:29 +01:00
}
2022-09-06 17:07:35 +02:00
myContactCard.Name = MyName
myContactCard.ContactPublicKey = peer.MyIdentity.Public
myContactCard.EncryptionPublicKey = peer.MyEncryptionKp.Public
myContactCard.LookupPublicKey = peer.MyLookupKp.Public
myContactCard.InvitationId = peer.InvitationId
2022-01-15 22:19:29 +01:00
id.Peers = append(id.Peers, peer)
return &myContactCard, nil
2021-10-18 21:05:44 +02:00
}
func (id *Identity) CheckInvitation(ReceivedContact *meowlib.ContactCard) (isAnswer bool, proposedNick string, receivedNick string) {
for _, p := range id.Peers {
if p.InvitationId == ReceivedContact.InvitationId {
return true, p.Name, ReceivedContact.Name
}
}
return false, "", ReceivedContact.Name
}
func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageServerIdxs []int, ReceivedContact *meowlib.ContactCard) *meowlib.ContactCard {
var peer Peer
var myContactCard meowlib.ContactCard
peer.MyIdentity = meowlib.NewKeyPair()
peer.MyEncryptionKp = meowlib.NewKeyPair()
peer.MyLookupKp = meowlib.NewKeyPair()
if ContactName != "" {
peer.Name = ContactName
} else {
peer.Name = ReceivedContact.Name
}
2022-09-06 17:07:35 +02:00
peer.Contact = *ReceivedContact
for _, i := range MessageServerIdxs {
srv := id.MessageServers.Servers[i].ServerData
myContactCard.PullServers = append(myContactCard.PullServers, &srv)
}
myContactCard.Name = MyName
myContactCard.ContactPublicKey = peer.MyIdentity.Public
myContactCard.EncryptionPublicKey = peer.MyEncryptionKp.Public
myContactCard.LookupPublicKey = peer.MyLookupKp.Public
2022-12-05 19:20:00 +01:00
myContactCard.InvitationId = ReceivedContact.InvitationId
id.Peers = append(id.Peers, peer)
return &myContactCard
}
func (id *Identity) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) error {
for i, p := range id.Peers {
if p.InvitationId == ReceivedContact.InvitationId {
id.Peers[i].Contact = *ReceivedContact
return nil
}
}
return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId)
2021-10-18 21:05:44 +02:00
}
func LoadIdentity(filename string, password string) (*Identity, error) {
2022-01-15 22:19:29 +01:00
var id Identity
GetConfig().memoryPassword = password
GetConfig().identityFile = filename
2022-12-02 23:18:13 +01:00
indata, err := os.ReadFile(filename)
2022-01-15 22:19:29 +01:00
if err != nil {
return nil, err
}
pass, err := helper.DecryptMessageWithPassword([]byte(password), string(indata))
2022-09-02 12:07:21 +02:00
if err != nil {
2022-01-15 22:19:29 +01:00
return nil, err
}
2022-09-02 12:07:21 +02:00
err = json.Unmarshal([]byte(pass), &id)
2022-01-15 22:19:29 +01:00
return &id, err
}
2021-10-18 21:05:44 +02:00
func (id *Identity) Save() error {
2022-01-15 22:19:29 +01:00
b, _ := json.Marshal(id)
armor, err := helper.EncryptMessageWithPassword([]byte(GetConfig().memoryPassword), string(b))
2022-01-15 22:19:29 +01:00
if err != nil {
return err
}
2022-12-02 23:18:13 +01:00
err = os.WriteFile(GetConfig().identityFile, []byte(armor), 0600)
2022-01-15 22:19:29 +01:00
return err
2021-10-18 21:05:44 +02:00
}