Add notification for trustworthy/untrustworthy

This commit is contained in:
Andrea Maria Piana 2022-10-28 12:37:46 +01:00
parent 98f7324ae1
commit 2572321063
9 changed files with 304 additions and 51 deletions

View File

@ -1 +1 @@
0.115.0
0.115.1

View File

@ -738,7 +738,6 @@ func (db sqlitePersistence) UpdateActivityCenterNotificationFields(id types.HexB
return err
}
_, err = db.db.Exec(`UPDATE activity_center_notifications SET message = ?, reply_message = ?, contact_verification_status = ? WHERE id = ?`, encodedMessage, encodedReplyMessage, status, id)
return err

View File

@ -65,6 +65,8 @@ const (
ContactVerificationStatePending ContactVerificationState = iota + 1
ContactVerificationStateAccepted
ContactVerificationStateDeclined
ContactVerificationStateTrusted
ContactVerificationStateUntrustworthy
)
type CommandParameters struct {

View File

@ -16,6 +16,7 @@ import (
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/protocol/verification"
)
@ -284,7 +285,7 @@ func (m *Messenger) AcceptContactVerificationRequest(ctx context.Context, id str
notification.ContactVerificationStatus = verification.RequestStatusACCEPTED
message := notification.Message
message.ContactVerificationState = common.ContactVerificationStateAccepted
notification.ReplyMessage = replyMessage
notification.ReplyMessage = replyMessage
err := m.persistence.UpdateActivityCenterNotificationFields(notification.ID, message, replyMessage, verification.RequestStatusACCEPTED)
if err != nil {
@ -298,27 +299,43 @@ func (m *Messenger) AcceptContactVerificationRequest(ctx context.Context, id str
return resp, nil
}
func (m *Messenger) VerifiedTrusted(ctx context.Context, contactID string) error {
contact, ok := m.allContacts.Load(contactID)
if !ok || !contact.Added || !contact.HasAddedUs {
return errors.New("must be a mutual contact")
func (m *Messenger) VerifiedTrusted(ctx context.Context, request *requests.VerifiedTrusted) (*MessengerResponse, error) {
err := request.Validate()
if err != nil {
return nil, err
}
// Pull one from the db if there
notification, err := m.persistence.GetActivityCenterNotificationByID(request.ID)
if err != nil {
return nil, err
}
err := m.verificationDatabase.SetTrustStatus(contactID, verification.TrustStatusTRUSTED, m.getTimesource().GetCurrentTime())
if notification == nil || notification.ReplyMessage == nil {
return nil, errors.New("could not find notification")
}
contactID := notification.ReplyMessage.From
contact, ok := m.allContacts.Load(contactID)
if !ok || !contact.Added || !contact.HasAddedUs {
return nil, errors.New("must be a mutual contact")
}
err = m.verificationDatabase.SetTrustStatus(contactID, verification.TrustStatusTRUSTED, m.getTimesource().GetCurrentTime())
if err != nil {
return err
return nil, err
}
err = m.SyncTrustedUser(context.Background(), contactID, verification.TrustStatusTRUSTED)
if err != nil {
return err
return nil, err
}
contact.VerificationStatus = VerificationStatusVERIFIED
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
err = m.persistence.SaveContact(contact, nil)
if err != nil {
return err
return nil, err
}
chat, ok := m.allChats.Load(contactID)
@ -326,20 +343,20 @@ func (m *Messenger) VerifiedTrusted(ctx context.Context, contactID string) error
if !ok {
publicKey, err := contact.PublicKey()
if err != nil {
return err
return nil, err
}
chat = OneToOneFromPublicKey(publicKey, m.getTimesource())
// We don't want to show the chat to the user
chat.Active = false
}
request := &protobuf.ContactVerificationTrusted{
r := &protobuf.ContactVerificationTrusted{
Clock: clock,
}
encodedMessage, err := proto.Marshal(request)
encodedMessage, err := proto.Marshal(r)
if err != nil {
return err
return nil, err
}
_, err = m.dispatchMessage(ctx, common.RawMessage{
@ -350,69 +367,133 @@ func (m *Messenger) VerifiedTrusted(ctx context.Context, contactID string) error
})
if err != nil {
return err
return nil, err
}
verifRequest, err := m.verificationDatabase.GetVerificationRequestSentTo(contactID)
if err != nil {
return err
return nil, err
}
if verifRequest == nil {
return errors.New("no contact verification found")
return nil, errors.New("no contact verification found")
}
verifRequest.RequestStatus = verification.RequestStatusTRUSTED
verifRequest.RepliedAt = clock
err = m.verificationDatabase.SaveVerificationRequest(verifRequest)
if err != nil {
return err
return nil, err
}
err = m.SyncVerificationRequest(context.Background(), verifRequest)
if err != nil {
return err
return nil, err
}
// We sync the contact with the other devices
err = m.syncContact(context.Background(), contact)
if err != nil {
return err
return nil, err
}
return nil
response := &MessengerResponse{}
notification.ContactVerificationStatus = verification.RequestStatusTRUSTED
notification.Message.ContactVerificationState = common.ContactVerificationStateTrusted
err = m.persistence.UpdateActivityCenterNotificationFields(notification.ID, notification.Message, notification.ReplyMessage, notification.ContactVerificationStatus)
if err != nil {
return nil, err
}
msg, err := m.persistence.MessageByID(notification.ReplyMessage.ID)
if err != nil {
return nil, err
}
msg.ContactVerificationState = common.ContactVerificationStateTrusted
err = m.persistence.SaveMessages([]*common.Message{msg})
if err != nil {
return nil, err
}
response.AddMessage(msg)
response.AddActivityCenterNotification(notification)
return response, nil
}
func (m *Messenger) VerifiedUntrustworthy(ctx context.Context, contactID string) error {
contact, ok := m.allContacts.Load(contactID)
if !ok || !contact.Added || !contact.HasAddedUs {
return errors.New("must be a mutual contact")
func (m *Messenger) VerifiedUntrustworthy(ctx context.Context, request *requests.VerifiedUntrustworthy) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
err := m.verificationDatabase.SetTrustStatus(contactID, verification.TrustStatusUNTRUSTWORTHY, m.getTimesource().GetCurrentTime())
// Pull one from the db if there
notification, err := m.persistence.GetActivityCenterNotificationByID(request.ID)
if err != nil {
return err
return nil, err
}
if notification == nil || notification.ReplyMessage == nil {
return nil, errors.New("could not find notification")
}
contactID := notification.ReplyMessage.From
contact, ok := m.allContacts.Load(contactID)
if !ok || !contact.Added || !contact.HasAddedUs {
return nil, errors.New("must be a mutual contact")
}
err = m.verificationDatabase.SetTrustStatus(contactID, verification.TrustStatusUNTRUSTWORTHY, m.getTimesource().GetCurrentTime())
if err != nil {
return nil, err
}
err = m.SyncTrustedUser(context.Background(), contactID, verification.TrustStatusUNTRUSTWORTHY)
if err != nil {
return err
return nil, err
}
contact.VerificationStatus = VerificationStatusVERIFIED
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
err = m.persistence.SaveContact(contact, nil)
if err != nil {
return err
return nil, err
}
// We sync the contact with the other devices
err = m.syncContact(context.Background(), contact)
if err != nil {
return err
return nil, err
}
return nil
response := &MessengerResponse{}
notification.ContactVerificationStatus = verification.RequestStatusUNTRUSTWORTHY
notification.Message.ContactVerificationState = common.ContactVerificationStateUntrustworthy
err = m.persistence.UpdateActivityCenterNotificationFields(notification.ID, notification.Message, notification.ReplyMessage, notification.ContactVerificationStatus)
if err != nil {
return nil, err
}
msg, err := m.persistence.MessageByID(notification.ReplyMessage.ID)
if err != nil {
return nil, err
}
msg.ContactVerificationState = common.ContactVerificationStateUntrustworthy
err = m.persistence.SaveMessages([]*common.Message{msg})
if err != nil {
return nil, err
}
response.AddMessage(msg)
response.AddActivityCenterNotification(notification)
return response, nil
}
func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id string) (*MessengerResponse, error) {
@ -730,7 +811,7 @@ func (m *Messenger) HandleAcceptContactVerification(state *ReceivedMessageState,
if err != nil {
return err
}
msg.ContactVerificationState = common.ContactVerificationStateAccepted
msg.ContactVerificationState = common.ContactVerificationStateAccepted
state.Response.AddMessage(msg)
@ -903,7 +984,7 @@ func (m *Messenger) createContactVerificationNotification(contact *Contact, mess
Type: ActivityCenterNotificationTypeContactVerification,
Author: messageState.CurrentMessageState.Contact.ID,
Message: chatMessage,
ReplyMessage: replyMessage,
ReplyMessage: replyMessage,
Timestamp: messageState.CurrentMessageState.WhisperTimestamp,
ChatID: contact.ID,
ContactVerificationStatus: vr.RequestStatus,

View File

@ -178,7 +178,7 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() {
verificationRequestID := resp.VerificationRequests[0].ID
s.Require().Len(resp.Messages(), 1)
s.Require().NotEmpty(resp.Messages()[0].OutgoingStatus)
s.Require().NotEmpty(resp.Messages()[0].OutgoingStatus)
s.Require().Equal(challenge, resp.Messages()[0].Text)
s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState)
@ -200,7 +200,7 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() {
s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text)
s.Require().Equal(common.ContactVerificationStatePending, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState)
s.Require().Len(resp.Messages(), 1)
s.Require().Empty(resp.Messages()[0].OutgoingStatus)
s.Require().Empty(resp.Messages()[0].OutgoingStatus)
s.Require().Equal(challenge, resp.Messages()[0].Text)
s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState)
@ -238,21 +238,21 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() {
s.Require().Len(resp.VerificationRequests, 1)
s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID)
messages := resp.Messages()
messages := resp.Messages()
s.Require().Len(messages, 2)
var originalMessage *common.Message
var replyMessage *common.Message
var originalMessage *common.Message
var replyMessage *common.Message
if messages[0].ID == resp.VerificationRequests[0].ID {
originalMessage = messages[0]
replyMessage = messages[1]
} else {
originalMessage = messages[1]
replyMessage = messages[0]
}
if messages[0].ID == resp.VerificationRequests[0].ID {
originalMessage = messages[0]
replyMessage = messages[1]
} else {
originalMessage = messages[1]
replyMessage = messages[0]
}
s.Require().Equal(common.ContactVerificationStateAccepted, originalMessage.ContactVerificationState)
// Not sure this is the right state for this, it should probably be pendingtrustedverification or something
// Not sure this is the right state for this, it should probably be pendingtrustedverification or something
s.Require().Equal(common.ContactVerificationStateAccepted, replyMessage.ContactVerificationState)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
@ -263,6 +263,134 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() {
s.Require().NotNil(resp.ActivityCenterNotifications()[0].ReplyMessage)
s.Require().Empty(resp.ActivityCenterNotifications()[0].ReplyMessage.OutgoingStatus)
s.Require().Equal("hello back", resp.ActivityCenterNotifications()[0].ReplyMessage.Text)
resp, err = s.m.VerifiedTrusted(context.Background(), &requests.VerifiedTrusted{ID: types.FromHex(verificationRequestID)})
s.Require().NoError(err)
s.Require().NotNil(resp)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusTRUSTED)
s.Require().Equal(common.ContactVerificationStateTrusted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(common.ContactVerificationStateTrusted, resp.Messages()[0].ContactVerificationState)
}
func (s *MessengerVerificationRequests) TestUnthrustworthyVerificationRequests() {
theirMessenger := s.newMessenger(s.shh)
_, err := theirMessenger.Start()
s.Require().NoError(err)
s.mutualContact(theirMessenger)
theirPk := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
challenge := "challenge"
resp, err := s.m.SendContactVerificationRequest(context.Background(), theirPk, challenge)
s.Require().NoError(err)
s.Require().Len(resp.VerificationRequests, 1)
verificationRequestID := resp.VerificationRequests[0].ID
s.Require().Len(resp.Messages(), 1)
s.Require().NotEmpty(resp.Messages()[0].OutgoingStatus)
s.Require().Equal(challenge, resp.Messages()[0].Text)
s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState)
// Wait for the message to reach its destination
resp, err = WaitOnMessengerResponse(
theirMessenger,
func(r *MessengerResponse) bool {
return len(r.VerificationRequests) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
s.Require().NoError(err)
s.Require().Len(resp.VerificationRequests, 1)
s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID)
s.Require().Equal(resp.ActivityCenterNotifications()[0].Type, ActivityCenterNotificationTypeContactVerification)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusPENDING)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text)
s.Require().Equal(common.ContactVerificationStatePending, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState)
s.Require().Len(resp.Messages(), 1)
s.Require().Empty(resp.Messages()[0].OutgoingStatus)
s.Require().Equal(challenge, resp.Messages()[0].Text)
s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState)
resp, err = theirMessenger.AcceptContactVerificationRequest(context.Background(), verificationRequestID, "hello back")
s.Require().NoError(err)
s.Require().NoError(err)
s.Require().Len(resp.VerificationRequests, 1)
s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID)
s.Require().Equal(resp.VerificationRequests[0].RequestStatus, verification.RequestStatusACCEPTED)
s.Require().NotEmpty(resp.VerificationRequests[0].RepliedAt)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED)
s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(common.ContactVerificationStateAccepted, resp.Messages()[0].ContactVerificationState)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].ReplyMessage)
s.Require().NotEmpty(resp.ActivityCenterNotifications()[0].ReplyMessage.OutgoingStatus)
s.Require().Equal("hello back", resp.ActivityCenterNotifications()[0].ReplyMessage.Text)
// Wait for the message to reach its destination
resp, err = WaitOnMessengerResponse(
s.m,
func(r *MessengerResponse) bool {
return len(r.VerificationRequests) > 0
},
"no messages",
)
s.Require().NoError(err)
s.Require().Len(resp.VerificationRequests, 1)
s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID)
messages := resp.Messages()
s.Require().Len(messages, 2)
var originalMessage *common.Message
var replyMessage *common.Message
if messages[0].ID == resp.VerificationRequests[0].ID {
originalMessage = messages[0]
replyMessage = messages[1]
} else {
originalMessage = messages[1]
replyMessage = messages[0]
}
s.Require().Equal(common.ContactVerificationStateAccepted, originalMessage.ContactVerificationState)
// Not sure this is the right state for this, it should probably be pendingtrustedverification or something
s.Require().Equal(common.ContactVerificationStateAccepted, replyMessage.ContactVerificationState)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED)
s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].ReplyMessage)
s.Require().Empty(resp.ActivityCenterNotifications()[0].ReplyMessage.OutgoingStatus)
s.Require().Equal("hello back", resp.ActivityCenterNotifications()[0].ReplyMessage.Text)
resp, err = s.m.VerifiedUntrustworthy(context.Background(), &requests.VerifiedUntrustworthy{ID: types.FromHex(verificationRequestID)})
s.Require().NoError(err)
s.Require().NotNil(resp)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusUNTRUSTWORTHY)
s.Require().Equal(common.ContactVerificationStateUntrustworthy, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(common.ContactVerificationStateUntrustworthy, resp.Messages()[0].ContactVerificationState)
}
func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() {

View File

@ -0,0 +1,21 @@
package requests
import (
"errors"
"github.com/status-im/status-go/eth-node/types"
)
var ErrVerifiedTrustedInvalidID = errors.New("verified-trusted: invalid id")
type VerifiedTrusted struct {
ID types.HexBytes `json:"id"`
}
func (a *VerifiedTrusted) Validate() error {
if len(a.ID) == 0 {
return ErrVerifiedTrustedInvalidID
}
return nil
}

View File

@ -0,0 +1,21 @@
package requests
import (
"errors"
"github.com/status-im/status-go/eth-node/types"
)
var ErrVerifiedUntrustworthyInvalidID = errors.New("verified-untrustworthy: invalid id")
type VerifiedUntrustworthy struct {
ID types.HexBytes `json:"id"`
}
func (a *VerifiedUntrustworthy) Validate() error {
if len(a.ID) == 0 {
return ErrVerifiedUntrustworthyInvalidID
}
return nil
}

View File

@ -29,6 +29,7 @@ const (
RequestStatusDECLINED
RequestStatusCANCELED
RequestStatusTRUSTED
RequestStatusUNTRUSTWORTHY
)
type TrustStatus int

View File

@ -820,12 +820,12 @@ func (api *PublicAPI) DeclineContactVerificationRequest(ctx context.Context, con
return api.service.messenger.DeclineContactVerificationRequest(ctx, contactID)
}
func (api *PublicAPI) VerifiedTrusted(ctx context.Context, contactID string) error {
return api.service.messenger.VerifiedTrusted(ctx, contactID)
func (api *PublicAPI) VerifiedTrusted(ctx context.Context, request *requests.VerifiedTrusted) (*protocol.MessengerResponse, error) {
return api.service.messenger.VerifiedTrusted(ctx, request)
}
func (api *PublicAPI) VerifiedUntrustworthy(ctx context.Context, contactID string) error {
return api.service.messenger.VerifiedUntrustworthy(ctx, contactID)
func (api *PublicAPI) VerifiedUntrustworthy(ctx context.Context, request *requests.VerifiedUntrustworthy) (*protocol.MessengerResponse, error) {
return api.service.messenger.VerifiedUntrustworthy(ctx, request)
}
func (api *PublicAPI) SendPairInstallation(ctx context.Context) (*protocol.MessengerResponse, error) {