diff --git a/event/common.go b/event/common.go index ce214f8..1a6efd4 100644 --- a/event/common.go +++ b/event/common.go @@ -9,8 +9,14 @@ const ( ProtocolEngineStatus = Type("ProtocolEngineStatus") PeerRequest = Type("PeerRequest") + + // Blocking Events both Block and Unblock have the same structure + // attributes: + // RemotePeer: [eg "chpr7qm6op5vfcg2pi4vllco3h6aa7exexc4rqwnlupqhoogx2zgd6qd" BlockPeer = Type("BlockPeer") - JoinServer = Type("JoinServer") + UnblockPeer = Type("UnblockPeer") + + JoinServer = Type("JoinServer") ProtocolEngineStartListen = Type("ProtocolEngineStartListen") ProtocolEngineStopped = Type("ProtocolEngineStopped") diff --git a/model/profile.go b/model/profile.go index 1f7f6f4..964e94c 100644 --- a/model/profile.go +++ b/model/profile.go @@ -203,6 +203,19 @@ func (p *Profile) BlockPeer(onion string) (err error) { return } +// UnblockPeer unblocks a contact +func (p *Profile) UnblockPeer(onion string) (err error) { + p.lock.Lock() + defer p.lock.Unlock() + contact, ok := p.Contacts[onion] + if ok { + contact.Blocked = false + } else { + err = errors.New("peer does not exist") + } + return +} + // BlockedPeers calculates a list of Peers who have been Blocked. func (p *Profile) BlockedPeers() []string { blockedPeers := []string{} diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index faa9791..1bd1e24 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -36,6 +36,7 @@ type CwtchPeer interface { TrustPeer(string) error BlockPeer(string) error + UnblockPeer(string) error AcceptInvite(string) error RejectInvite(string) DeleteContact(string) @@ -279,6 +280,13 @@ func (cp *cwtchPeer) BlockPeer(peer string) error { return err } +// UnblockPeer blocks an existing peer relationship. +func (cp *cwtchPeer) UnblockPeer(peer string) error { + err := cp.Profile.UnblockPeer(peer) + cp.eventBus.Publish(event.NewEvent(event.UnblockPeer, map[event.Field]string{event.RemotePeer: peer})) + return err +} + // AcceptInvite accepts a given existing group invite func (cp *cwtchPeer) AcceptInvite(groupID string) error { err := cp.Profile.AcceptInvite(groupID) diff --git a/protocol/connections/engine.go b/protocol/connections/engine.go index 31e1495..7d454c7 100644 --- a/protocol/connections/engine.go +++ b/protocol/connections/engine.go @@ -79,6 +79,7 @@ func NewProtocolEngine(identity identity.Identity, privateKey ed25519.PrivateKey engine.eventManager.Subscribe(event.DeleteGroup, engine.queue.EventChannel) engine.eventManager.Subscribe(event.BlockPeer, engine.queue.EventChannel) + engine.eventManager.Subscribe(event.UnblockPeer, engine.queue.EventChannel) for _, peer := range blockedPeers { engine.blocked.Store(peer, true) } @@ -127,6 +128,11 @@ func (e *engine) eventHandler() { if err != nil { e.eventManager.Publish(event.NewEvent(event.SendMessageToPeerError, map[event.Field]string{event.RemotePeer: ev.Data[event.RemotePeer], event.Signature: ev.EventID, event.Error: "peer is offline or the connection has yet to finalize"})) } + case event.UnblockPeer: + // We simply remove the peer from our blocklist + // The UI has the responsibility to reinitiate contact with the peer. + // (this should happen periodically in any case) + e.blocked.Delete(ev.Data[event.RemotePeer]) case event.BlockPeer: e.blocked.Store(ev.Data[event.RemotePeer], true) connection, err := e.service.GetConnection(ev.Data[event.RemotePeer]) diff --git a/storage/profile_store.go b/storage/profile_store.go index 7491662..aef9ff4 100644 --- a/storage/profile_store.go +++ b/storage/profile_store.go @@ -45,6 +45,7 @@ func NewProfileWriterStore(eventManager event.Manager, directory, password strin go ps.eventHandler() ps.eventManager.Subscribe(event.BlockPeer, ps.queue.EventChannel) + ps.eventManager.Subscribe(event.UnblockPeer, ps.queue.EventChannel) ps.eventManager.Subscribe(event.PeerCreated, ps.queue.EventChannel) ps.eventManager.Subscribe(event.GroupCreated, ps.queue.EventChannel) ps.eventManager.Subscribe(event.SetProfileName, ps.queue.EventChannel) @@ -158,6 +159,12 @@ func (ps *profileStore) eventHandler() { contact.Blocked = true ps.save() } + case event.UnblockPeer: + contact, exists := ps.profile.GetContact(ev.Data[event.RemotePeer]) + if exists { + contact.Blocked = false + ps.save() + } case event.PeerCreated: var pp *model.PublicProfile json.Unmarshal([]byte(ev.Data[event.Data]), &pp)