2018-03-09 20:44:13 +00:00
|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
2019-01-29 20:56:59 +00:00
|
|
|
"encoding/hex"
|
2019-01-21 20:11:40 +00:00
|
|
|
"encoding/json"
|
2018-03-09 20:44:13 +00:00
|
|
|
"golang.org/x/crypto/ed25519"
|
2021-11-16 23:06:30 +00:00
|
|
|
"io"
|
2018-05-30 17:41:02 +00:00
|
|
|
"sync"
|
2018-03-09 20:44:13 +00:00
|
|
|
)
|
|
|
|
|
2020-06-16 00:16:04 +00:00
|
|
|
// Authorization is a type determining client assigned authorization to a peer
|
2021-11-19 20:27:52 +00:00
|
|
|
// Deprecated - Only used for Importing legacy profile formats
|
|
|
|
// Still used in some APIs in UI but will be replaced prior to full deprecation
|
2020-06-16 00:16:04 +00:00
|
|
|
type Authorization string
|
|
|
|
|
|
|
|
const (
|
2020-07-08 18:29:33 +00:00
|
|
|
// AuthUnknown is an initial state for a new unseen peer
|
2020-06-16 00:16:04 +00:00
|
|
|
AuthUnknown Authorization = "unknown"
|
|
|
|
// AuthApproved means the client has approved the peer, it can send messages to us, perform GetVals, etc
|
|
|
|
AuthApproved Authorization = "approved"
|
|
|
|
// AuthBlocked means the client has blocked the peer, it's messages and connections should be rejected
|
|
|
|
AuthBlocked Authorization = "blocked"
|
|
|
|
)
|
|
|
|
|
2018-03-15 16:33:26 +00:00
|
|
|
// PublicProfile is a local copy of a CwtchIdentity
|
2021-11-19 20:27:52 +00:00
|
|
|
// Deprecated - Only used for Importing legacy profile formats
|
2018-03-09 20:44:13 +00:00
|
|
|
type PublicProfile struct {
|
2019-10-18 23:56:10 +00:00
|
|
|
Name string
|
|
|
|
Ed25519PublicKey ed25519.PublicKey
|
2020-06-16 00:16:04 +00:00
|
|
|
Authorization Authorization
|
|
|
|
DeprecatedBlocked bool `json:"Blocked"`
|
2019-10-18 23:56:10 +00:00
|
|
|
Onion string
|
|
|
|
Attributes map[string]string
|
|
|
|
Timeline Timeline `json:"-"`
|
|
|
|
LocalID string // used by storage engine
|
|
|
|
State string `json:"-"`
|
|
|
|
lock sync.Mutex
|
2020-10-08 19:40:27 +00:00
|
|
|
UnacknowledgedMessages map[string]int
|
2018-03-09 20:44:13 +00:00
|
|
|
}
|
|
|
|
|
2018-03-15 16:33:26 +00:00
|
|
|
// Profile encapsulates all the attributes necessary to be a Cwtch Peer.
|
2021-11-19 20:27:52 +00:00
|
|
|
// Deprecated - Only used for Importing legacy profile formats
|
2018-03-09 20:44:13 +00:00
|
|
|
type Profile struct {
|
|
|
|
PublicProfile
|
2018-05-03 19:23:02 +00:00
|
|
|
Contacts map[string]*PublicProfile
|
2018-03-09 20:44:13 +00:00
|
|
|
Ed25519PrivateKey ed25519.PrivateKey
|
|
|
|
Groups map[string]*Group
|
|
|
|
}
|
|
|
|
|
2018-11-28 19:50:32 +00:00
|
|
|
// MaxGroupMessageLength is the maximum length of a message posted to a server group.
|
|
|
|
// TODO: Should this be per server?
|
2019-01-19 21:09:38 +00:00
|
|
|
const MaxGroupMessageLength = 1800
|
2018-11-28 19:50:32 +00:00
|
|
|
|
2021-11-16 23:06:30 +00:00
|
|
|
func getRandomness(arr *[]byte) {
|
|
|
|
if _, err := io.ReadFull(rand.Reader, (*arr)[:]); err != nil {
|
|
|
|
if err != nil {
|
|
|
|
// If we can't do randomness, just crash something is very very wrong and we are not going
|
|
|
|
// to resolve it here....
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-17 22:34:13 +00:00
|
|
|
// GenerateRandomID generates a random 16 byte hex id code
|
|
|
|
func GenerateRandomID() string {
|
|
|
|
randBytes := make([]byte, 16)
|
|
|
|
rand.Read(randBytes)
|
2021-11-23 22:45:25 +00:00
|
|
|
return hex.EncodeToString(randBytes)
|
2021-11-17 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
2019-07-19 17:27:50 +00:00
|
|
|
// GetCopy returns a full deep copy of the Profile struct and its members (timeline inclusion control by arg)
|
|
|
|
func (p *Profile) GetCopy(timeline bool) *Profile {
|
2019-01-21 20:11:40 +00:00
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
|
|
|
|
newp := new(Profile)
|
|
|
|
bytes, _ := json.Marshal(p)
|
|
|
|
json.Unmarshal(bytes, &newp)
|
2019-07-19 17:27:50 +00:00
|
|
|
|
|
|
|
if timeline {
|
|
|
|
for groupID := range newp.Groups {
|
2023-11-18 19:49:52 +00:00
|
|
|
if group, exists := newp.Groups[groupID]; exists {
|
|
|
|
if pGroup, exists := p.Groups[groupID]; exists {
|
|
|
|
group.Timeline = *(pGroup).Timeline.GetCopy()
|
|
|
|
}
|
|
|
|
}
|
2019-07-19 17:27:50 +00:00
|
|
|
}
|
2020-07-08 18:29:33 +00:00
|
|
|
|
|
|
|
for peerID := range newp.Contacts {
|
2023-11-18 19:49:52 +00:00
|
|
|
if peer, exists := newp.Contacts[peerID]; exists {
|
|
|
|
if pPeer, exists := p.Contacts[peerID]; exists {
|
|
|
|
peer.Timeline = *(pPeer).Timeline.GetCopy()
|
|
|
|
}
|
|
|
|
}
|
2020-07-08 18:29:33 +00:00
|
|
|
}
|
2019-07-19 17:27:50 +00:00
|
|
|
}
|
|
|
|
|
2019-01-21 20:11:40 +00:00
|
|
|
return newp
|
|
|
|
}
|