Official cwtch.im peer and server implementations. https://cwtch.im
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.6KB

  1. package app
  2. import (
  3. "cwtch.im/cwtch/event"
  4. "cwtch.im/cwtch/peer"
  5. "cwtch.im/cwtch/storage"
  6. "fmt"
  7. "git.openprivacy.ca/openprivacy/libricochet-go/log"
  8. "path"
  9. )
  10. type applicationClient struct {
  11. applicationBridge
  12. appletPeers
  13. appBus event.Manager
  14. }
  15. // NewAppClient returns an Application that acts as a client to a AppService, connected by the IPCBridge supplied
  16. func NewAppClient(appDirectory string, bridge event.IPCBridge) Application {
  17. appClient := &applicationClient{appletPeers: appletPeers{peers: make(map[string]peer.CwtchPeer)}, applicationBridge: applicationBridge{applicationCore: *newAppCore(appDirectory), bridge: bridge}, appBus: event.NewEventManager()}
  18. appClient.handle = appClient.handleEvent
  19. go appClient.listen()
  20. log.Infoln("Created new App Client")
  21. return appClient
  22. }
  23. // GetPrimaryBus returns the bus the Application uses for events that aren't peer specific
  24. func (ac *applicationClient) GetPrimaryBus() event.Manager {
  25. return ac.appBus
  26. }
  27. func (ac *applicationClient) handleEvent(ev *event.Event) {
  28. switch ev.EventType {
  29. case event.NewPeer:
  30. localID := ev.Data[event.Identity]
  31. password := ev.Data[event.Password]
  32. ac.newPeer(localID, password)
  33. case event.PeerError:
  34. ac.appBus.Publish(*ev)
  35. case event.AppError:
  36. ac.appBus.Publish(*ev)
  37. case event.ACNStatus:
  38. ac.appBus.Publish(*ev)
  39. }
  40. }
  41. func (ac *applicationClient) newPeer(localID, password string) {
  42. profile, err := storage.ReadProfile(path.Join(ac.directory, "profiles", localID), password)
  43. if err != nil {
  44. log.Errorf("Could not read profile for NewPeer event: %v\n", err)
  45. ac.appBus.Publish(event.NewEventList(event.PeerError, event.Error, fmt.Sprintf("Could not read profile for NewPeer event: %v\n", err)))
  46. return
  47. }
  48. _, exists := ac.peers[profile.Onion]
  49. if exists {
  50. log.Errorf("profile for onion %v already exists", profile.Onion)
  51. ac.appBus.Publish(event.NewEventList(event.PeerError, event.Error, fmt.Sprintf("profile for onion %v already exists", profile.Onion)))
  52. return
  53. }
  54. eventBus := event.NewIPCEventManager(ac.bridge, profile.Onion)
  55. peer := peer.FromProfile(profile)
  56. peer.Init(eventBus)
  57. ac.mutex.Lock()
  58. defer ac.mutex.Unlock()
  59. ac.peers[profile.Onion] = peer
  60. ac.eventBuses[profile.Onion] = eventBus
  61. ac.appBus.Publish(event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.Onion}))
  62. }
  63. // CreatePeer messages the service to create a new Peer with the given name
  64. func (ac *applicationClient) CreatePeer(name string, password string) {
  65. log.Infof("appClient CreatePeer %v\n", name)
  66. message := event.IPCMessage{Dest: DestApp, Message: event.NewEvent(event.CreatePeer, map[event.Field]string{event.ProfileName: name, event.Password: password})}
  67. ac.bridge.Write(&message)
  68. }
  69. // LoadProfiles messages the service to load any profiles for the given password
  70. func (ac *applicationClient) LoadProfiles(password string) {
  71. message := event.IPCMessage{Dest: DestApp, Message: event.NewEvent(event.LoadProfiles, map[event.Field]string{event.Password: password})}
  72. ac.bridge.Write(&message)
  73. }
  74. // ShutdownPeer shuts down a peer and removes it from the app's management
  75. func (ac *applicationClient) ShutdownPeer(onion string) {
  76. ac.mutex.Lock()
  77. defer ac.mutex.Unlock()
  78. ac.eventBuses[onion].Shutdown()
  79. delete(ac.eventBuses, onion)
  80. ac.peers[onion].Shutdown()
  81. delete(ac.peers, onion)
  82. message := event.IPCMessage{Dest: DestApp, Message: event.NewEvent(event.ShutdownPeer, map[event.Field]string{event.Identity: onion})}
  83. ac.bridge.Write(&message)
  84. }
  85. // Shutdown shuts down the application lcienr and all front end peer components
  86. func (ac *applicationClient) Shutdown() {
  87. for id := range ac.peers {
  88. ac.ShutdownPeer(id)
  89. }
  90. ac.applicationBridge.Shutdown()
  91. ac.appBus.Shutdown()
  92. }