From 976265a2874639fe1f3b248087f05dd9e15e886a Mon Sep 17 00:00:00 2001 From: Alexandr Stelnykovych Date: Wed, 6 May 2020 20:57:32 +0300 Subject: [PATCH] Notifying clients about account status --- go.sum | 1 + protocol/protocol.go | 13 +++++++------ protocol/protocol_handlers.go | 12 ++++++++++++ protocol/types/requests.go | 4 ++-- protocol/types/responses.go | 5 +++-- service/interfaces.go | 2 ++ service/service.go | 25 ++++++++++++++----------- 7 files changed, 41 insertions(+), 21 deletions(-) diff --git a/go.sum b/go.sum index d3af00c..6b4c08a 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,7 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20200226051749-491c5fce7268 h1:fnuNgko6vrkrxuKfTMd+0eOz50ziv+Wi+t38KUT3j+E= golang.org/x/net v0.0.0-20200226051749-491c5fce7268/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE= diff --git a/protocol/protocol.go b/protocol/protocol.go index 011c117..a587a3b 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -79,9 +79,10 @@ type Service interface { err error) SessionDelete() error - SessionStatus() ( + RequestSessionStatus() ( apiCode int, apiErrorMsg string, + sessionToken string, accountInfo preferences.AccountStatus, err error) @@ -616,7 +617,6 @@ func (p *Protocol) processRequest(conn net.Conn, message string) { // notify all clients about changed session status p.notifyClients(p.createHelloResponse()) - break case "SessionDelete": @@ -631,18 +631,19 @@ func (p *Protocol) processRequest(conn net.Conn, message string) { p.notifyClients(p.createHelloResponse()) break - case "SessionStatus": - var resp types.SessionStatusResp - apiCode, apiErrMsg, accountInfo, err := p._service.SessionStatus() + case "AccountStatus": + var resp types.AccountStatusResp + apiCode, apiErrMsg, sessionToken, accountInfo, err := p._service.RequestSessionStatus() if err != nil && apiCode == 0 { // if apiCode == 0 - it is not API error. Sending error response p.sendErrorResponse(conn, reqCmd, err) break } // Sending session info - resp = types.SessionStatusResp{ + resp = types.AccountStatusResp{ APIStatus: apiCode, APIErrorMessage: apiErrMsg, + SessionToken: sessionToken, Account: accountInfo} // send response diff --git a/protocol/protocol_handlers.go b/protocol/protocol_handlers.go index 9d0b1e2..761dfee 100644 --- a/protocol/protocol_handlers.go +++ b/protocol/protocol_handlers.go @@ -4,6 +4,7 @@ import ( "net" "github.com/ivpn/desktop-app-daemon/protocol/types" + "github.com/ivpn/desktop-app-daemon/service/preferences" "github.com/ivpn/desktop-app-daemon/version" ) @@ -22,6 +23,17 @@ func (p *Protocol) OnServiceSessionChanged() { p.notifyClients(&helloResp) } +// OnAccountStatus - handler of account status info. Notifying clients. +func (p *Protocol) OnAccountStatus(sessionToken string, accountInfo preferences.AccountStatus) { + if len(sessionToken) == 0 { + return + } + + p.notifyClients(&types.AccountStatusResp{ + SessionToken: sessionToken, + Account: accountInfo}) +} + // OnDNSChanged - DNS changed handler func (p *Protocol) OnDNSChanged(dns net.IP) { // notify all clients diff --git a/protocol/types/requests.go b/protocol/types/requests.go index c829e01..52c9ac4 100644 --- a/protocol/types/requests.go +++ b/protocol/types/requests.go @@ -167,8 +167,8 @@ type SessionDelete struct { CommandBase } -// SessionStatus get session status -type SessionStatus struct { +// AccountStatus get account status +type AccountStatus struct { CommandBase } diff --git a/protocol/types/responses.go b/protocol/types/responses.go index 57adb1e..0eb3e81 100644 --- a/protocol/types/responses.go +++ b/protocol/types/responses.go @@ -77,11 +77,12 @@ type SessionNewResp struct { Account preferences.AccountStatus } -// SessionStatusResp - information about created session (or error info) -type SessionStatusResp struct { +// AccountStatusResp - information about account status (or error info) +type AccountStatusResp struct { CommandBase APIStatus int APIErrorMessage string + SessionToken string Account preferences.AccountStatus } diff --git a/service/interfaces.go b/service/interfaces.go index 3ecbda6..fe42fa9 100644 --- a/service/interfaces.go +++ b/service/interfaces.go @@ -5,6 +5,7 @@ import ( "time" "github.com/ivpn/desktop-app-daemon/api/types" + "github.com/ivpn/desktop-app-daemon/service/preferences" "github.com/ivpn/desktop-app-daemon/service/wgkeys" ) @@ -34,6 +35,7 @@ type IWgKeysManager interface { // IServiceEventsReceiver is the receiver for service events (normally, it is protocol object) type IServiceEventsReceiver interface { OnServiceSessionChanged() + OnAccountStatus(sessionToken string, account preferences.AccountStatus) OnDNSChanged(dns net.IP) OnKillSwitchStateChanged() } diff --git a/service/service.go b/service/service.go index 37acaaf..5b32025 100644 --- a/service/service.go +++ b/service/service.go @@ -117,7 +117,7 @@ func (s *Service) init() error { } // Check session status (start as go-routine to do not block service initialisation) - go s.SessionStatus() + go s.RequestSessionStatus() // Start session status checker s.startSessionChecker() @@ -304,7 +304,7 @@ func (s *Service) connect(vpnProc vpn.Process, manualDNS net.IP, firewallDuringC } // check session status each disconnection (asynchronously, in separate goroutine) - defer func() { go s.SessionStatus() }() + defer func() { go s.RequestSessionStatus() }() s._connectMutex.Lock() defer s._connectMutex.Unlock() @@ -986,16 +986,17 @@ func (s *Service) logOut(needToDeleteOnBackend bool) error { return nil } -// SessionStatus receives session status -func (s *Service) SessionStatus() ( +// RequestSessionStatus receives session status +func (s *Service) RequestSessionStatus() ( apiCode int, apiErrorMsg string, + sessionToken string, accountInfo preferences.AccountStatus, err error) { session := s.Preferences().Session if session.IsLoggedIn() == false { - return apiCode, "", accountInfo, ErrorNotLoggedIn{} + return apiCode, "", "", accountInfo, ErrorNotLoggedIn{} } log.Info("Requesting session status...") @@ -1007,7 +1008,7 @@ func (s *Service) SessionStatus() ( // It could happen that logout\login was performed during the session check // Ignoring result if there is already a new session log.Info("Ignoring requested session status result. Local session already changed.") - return apiCode, "", accountInfo, ErrorNotLoggedIn{} + return apiCode, "", "", accountInfo, ErrorNotLoggedIn{} } apiCode = 0 @@ -1025,22 +1026,24 @@ func (s *Service) SessionStatus() ( if err != nil { // in case of other API error if apiErr != nil { - return apiCode, apiErr.Message, accountInfo, err + return apiCode, apiErr.Message, "", accountInfo, err } // not API error - return apiCode, "", accountInfo, err + return apiCode, "", "", accountInfo, err } if stat == nil { - return apiCode, "", accountInfo, fmt.Errorf("unexpected error when creating requesting session status") + return apiCode, "", "", accountInfo, fmt.Errorf("unexpected error when creating requesting session status") } // get account status info accountInfo = s.createAccountStatus(*stat) + // notify about account status + s._evtReceiver.OnAccountStatus(session.Session, accountInfo) // success - return apiCode, "", accountInfo, nil + return apiCode, "", session.Session, accountInfo, nil } func (s *Service) createAccountStatus(apiResp types.ServiceStatusAPIResp) preferences.AccountStatus { @@ -1084,7 +1087,7 @@ func (s *Service) startSessionChecker() { } // check status - s.SessionStatus() + s.RequestSessionStatus() // if not logged-in - no sense to check status anymore session := s.Preferences().Session