Skip to content

Commit

Permalink
Merge pull request #81 from loophole/fix/concurrent_messages
Browse files Browse the repository at this point in the history
Replace common log functions with concurrency safe ones
  • Loading branch information
Morishiri committed Dec 22, 2020
2 parents 5f3291e + 15d3a47 commit 721c5e7
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 497 deletions.
12 changes: 6 additions & 6 deletions cmd/account_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"fmt"
"os"

"github.com/loophole/cli/internal/pkg/communication"
"github.com/loophole/cli/internal/pkg/token"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

Expand All @@ -20,23 +20,23 @@ Running this command as not logged in user will prompt you to open URL and use t
Running this command as logged in user will fail, in cae you want to relogin then you need to log out first`,
Run: func(cmd *cobra.Command, args []string) {
if token.IsTokenSaved() {
log.Fatal().Msg(fmt.Sprintf("Already logged in, please use `%s account logout` first to re-login", os.Args[0]))
communication.LogFatalMsg(fmt.Sprintf("Already logged in, please use `%s account logout` first to re-login", os.Args[0]))
os.Exit(1)
}

deviceCodeSpec, err := token.RegisterDevice()
if err != nil {
log.Fatal().Err(err).Msg("Error obtaining device code")
communication.LogFatalErr("Error obtaining device code", err)
}
tokens, err := token.PollForToken(deviceCodeSpec.DeviceCode, deviceCodeSpec.Interval)
if err != nil {
log.Fatal().Err(err).Msg("Error obtaining token")
communication.LogFatalErr("Error obtaining token", err)
}
err = token.SaveToken(tokens)
if err != nil {
log.Fatal().Err(err).Msg("Error saving token")
communication.LogFatalErr("Error saving token", err)
}
log.Info().Msg("Logged in succesfully")
communication.LogInfo("Logged in successfully")
},
}

Expand Down
8 changes: 4 additions & 4 deletions cmd/account_logout.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package cmd

import (
"github.com/loophole/cli/internal/pkg/communication"
"github.com/loophole/cli/internal/pkg/token"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

Expand All @@ -14,14 +14,14 @@ var logoutCmd = &cobra.Command{
In regular scenario you should not need to use it, as tokens are getting refreshed automatically.`,
Run: func(cmd *cobra.Command, args []string) {
if !token.IsTokenSaved() {
log.Fatal().Msg("Not logged in, nothing to do")
communication.LogFatalMsg("Not logged in, nothing to do")
}

err := token.DeleteTokens()
if err != nil {
log.Fatal().Err(err).Msg("There as a problem logging out")
communication.LogFatalErr("There as a problem logging out", err)
}
log.Info().Msg("Logged out succesfully")
communication.LogInfo("Logged out succesfully")
},
}

Expand Down
9 changes: 2 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,16 @@ go 1.14
require (
github.com/abbot/go-http-auth v0.4.0
github.com/briandowns/spinner v1.11.1
github.com/coreos/etcd v3.3.10+incompatible
github.com/go-acme/lego/v3 v3.7.0
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381
github.com/mattn/go-colorable v0.1.2
github.com/mdp/qrterminal v1.0.1
github.com/mitchellh/go-homedir v1.1.0
github.com/rs/zerolog v1.19.0
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.4.0
go.uber.org/zap v1.15.0
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
k8s.io/apimachinery v0.18.5
golang.org/x/text v0.3.2 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
457 changes: 4 additions & 453 deletions go.sum

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions internal/app/loophole/loophole.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ func registerDomain(apiURL string, publicKey *ssh.PublicKey, requestedSiteID, ve
log.Error().Int("status", requestErr.StatusCode).Msg("Request ended")
log.Error().Msg(requestErr.Message)
log.Error().Msg(fmt.Sprintf("Details: %s", requestErr.Details))
log.Fatal().Msg("Please fix the above issue and try again")
communication.LogFatalMsg("Please fix the above issue and try again")
} else {
log.Fatal().Err(err).Msg("Something unexpected happened, please let developers know")
communication.LogFatalErr("Something unexpected happened, please let developers know", err)
}
}
communication.LoadingSuccess()
Expand All @@ -88,7 +88,7 @@ func connectViaSSH(gatewayEndpoint lm.Endpoint, username string, authMethod ssh.
serverSSHConnHTTPS, err = ssh.Dial("tcp", gatewayEndpoint.URI(), sshConfigHTTPS)
if err != nil {
communication.LoadingFailure()
log.Info().Msg(fmt.Sprintf("SSH Connection failed, retrying in 10 seconds... (Attempt %d/%d)", i+1, sshRetries))
communication.LogInfo(fmt.Sprintf("SSH Connection failed, retrying in 10 seconds... (Attempt %d/%d)", i+1, sshRetries))
time.Sleep(10 * time.Second)
} else {
sshSuccess = true
Expand All @@ -97,7 +97,7 @@ func connectViaSSH(gatewayEndpoint lm.Endpoint, username string, authMethod ssh.
if !sshSuccess {
communication.WriteRed("An error occured while dialing into SSH. If your connection has been running for a while")
communication.WriteRed("this might be caused by the server shutting down your connection.")
log.Fatal().Err(err).Msg("Dialing SSH Gateway for HTTPS failed.")
communication.LogFatalErr("Dialing SSH Gateway for HTTPS failed.", err)
}
if el := log.Debug(); el.Enabled() {
fmt.Println()
Expand Down Expand Up @@ -131,7 +131,7 @@ func createTLSReverseProxy(localEndpoint lm.Endpoint, siteID string, basicAuthUs
server, err := serverBuilder.Build()
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("Something went wrong while creating server")
communication.LogFatalErr("Something went wrong while creating server", err)
}
return server
}
Expand All @@ -145,7 +145,7 @@ func startLocalHTTPServer(server *http.Server) *lm.Endpoint {
localListener, err := net.Listen("tcp", ":0")
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("Failed to listen on TLS proxy for HTTPS")
communication.LogFatalErr("Failed to listen on TLS proxy for HTTPS", err)
}
localListenerEndpoint := &lm.Endpoint{
Host: "127.0.0.1",
Expand All @@ -160,7 +160,7 @@ func startLocalHTTPServer(server *http.Server) *lm.Endpoint {
err := server.ServeTLS(localListener, "", "")
if err != nil {
communication.LoadingFailure()
log.Fatal().Msg("Failed to start TLS server")
communication.LogFatalMsg("Failed to start TLS server")
}
}()
if el := log.Debug(); el.Enabled() {
Expand All @@ -174,7 +174,7 @@ func startRemoteForwardServer(serverSSHConnHTTPS *ssh.Client) net.Listener {
listenerHTTPSOverSSH, err := serverSSHConnHTTPS.Listen("tcp", remoteEndpoint.URI())
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("Listening on remote endpoint for HTTPS failed")
communication.LogFatalErr("Listening on remote endpoint for HTTPS failed", err)
}
if el := log.Debug(); el.Enabled() {
fmt.Println()
Expand All @@ -187,7 +187,7 @@ func parsePublicKey(identityFile string) (ssh.AuthMethod, ssh.PublicKey) {
publicKeyAuthMethod, publicKey, err := keys.ParsePublicKey(identityFile)
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("No public key available")
communication.LogFatalErr("No public key available", err)
}

return publicKeyAuthMethod, publicKey
Expand All @@ -209,7 +209,7 @@ func getStaticFileServer(path string, siteID string, basicAuthUsername string, b
server, err := serverBuilder.Build()
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("Something went wrong while creating server")
communication.LogFatalErr("Something went wrong while creating server", err)
}
return server
}
Expand All @@ -230,7 +230,7 @@ func getWebdavServer(path string, siteID string, basicAuthUsername string, basic
server, err := serverBuilder.Build()
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("Something went wrong while creating server")
communication.LogFatalErr("Something went wrong while creating server", err)
}
return server
}
Expand All @@ -239,7 +239,7 @@ func listenOnRemoteEndpoint(serverSSHConnHTTPS *ssh.Client) net.Listener {
listenerHTTPSOverSSH, err := serverSSHConnHTTPS.Listen("tcp", remoteEndpoint.URI())
if err != nil {
communication.LoadingFailure()
log.Fatal().Err(err).Msg("Listening on remote endpoint for HTTPS failed")
communication.LogFatalErr("Listening on remote endpoint for HTTPS failed", err)
}
return listenerHTTPSOverSSH
}
Expand Down Expand Up @@ -297,7 +297,7 @@ func forward(remoteEndpointSpecs lm.RemoteEndpointSpecs, displayOptions lm.Displ
defer listenerHTTPSOverSSH.Close()

go func() {
log.Info().Msg("Issuing request to provision certificate")
communication.LogInfo("Issuing request to provision certificate")
var netTransport = &http.Transport{
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
Expand All @@ -313,7 +313,7 @@ func forward(remoteEndpointSpecs lm.RemoteEndpointSpecs, displayOptions lm.Displ
if err != nil {
log.Error().Msg("TLS Certificate failed to provision. Will be obtained with first request made by any client, therefore first execution may be slower")
} else {
log.Info().Msg("TLS Certificate successfully provisioned")
communication.LogInfo("TLS Certificate successfully provisioned")
}
}()

Expand All @@ -322,7 +322,7 @@ func forward(remoteEndpointSpecs lm.RemoteEndpointSpecs, displayOptions lm.Displ
for {
client, err := listenerHTTPSOverSSH.Accept()
if err == io.EOF {
log.Info().Err(err).Msg("Connection dropped, reconnecting...")
communication.LogInfo(err.Error() + " Connection dropped, reconnecting...")
listenerHTTPSOverSSH.Close()
serverSSHConnHTTPS = connectViaSSH(remoteEndpointSpecs.GatewayEndpoint, siteID, authMethod)
defer serverSSHConnHTTPS.Close()
Expand All @@ -335,10 +335,10 @@ func forward(remoteEndpointSpecs lm.RemoteEndpointSpecs, displayOptions lm.Displ
}
closehandler.SuccessfulConnectionOccured()
go func() {
log.Info().Msg("Succeeded to accept connection over HTTPS")
communication.LogInfo("Succeeded to accept connection over HTTPS")
local, err := net.Dial("tcp", localListenerEndpoint.URI())
if err != nil {
log.Fatal().Err(err).Msg("Dialing into local proxy for HTTPS failed")
communication.LogFatalErr("Dialing into local proxy for HTTPS failed", err)
}
if el := log.Debug(); el.Enabled() {
el.Msg("Dialing into local proxy for HTTPS succeeded")
Expand Down
10 changes: 5 additions & 5 deletions internal/pkg/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ import (
"os"
"path"

"github.com/loophole/cli/internal/pkg/communication"
"github.com/mitchellh/go-homedir"
"github.com/rs/zerolog/log"
)

// GetLocalStorageDir returns local directory for loophole cache purposes
func GetLocalStorageDir(directoryName string) string {
home, err := homedir.Dir()
if err != nil {
log.Fatal().Err(err).Msg("Error reading user home directory ")
communication.LogFatalErr("Error reading user home directory ", err)
}

dirName := path.Join(home, ".loophole", directoryName)
err = os.MkdirAll(dirName, os.ModePerm)
if err != nil {
log.Fatal().Err(err).Msg("Error creating local cache directory")
communication.LogFatalErr("Error creating local cache directory", err)
}
return dirName
}
Expand All @@ -27,12 +27,12 @@ func GetLocalStorageDir(directoryName string) string {
func GetLocalStorageFile(fileName string, directoryName string) string {
home, err := homedir.Dir()
if err != nil {
log.Fatal().Err(err).Msg("Error reading user home directory ")
communication.LogFatalErr("Error reading user home directory ", err)
}
dirName := path.Join(home, ".loophole", directoryName)
err = os.MkdirAll(dirName, os.ModePerm)
if err != nil {
log.Fatal().Err(err).Msg("Error creating local cache directory")
communication.LogFatalErr("Error creating local cache directory", err)
}

return path.Join(dirName, fileName)
Expand Down
3 changes: 1 addition & 2 deletions internal/pkg/closehandler/closehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"syscall"

"github.com/loophole/cli/internal/pkg/communication"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/ssh/terminal"
)

Expand All @@ -19,7 +18,7 @@ func SetupCloseHandler(feedbackFormURL string) {
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
terminalState, err := terminal.GetState(int(os.Stdin.Fd()))
if err != nil {
log.Fatal().Err(err).Msg("Error saving terminal state")
communication.LogFatalErr("Error saving terminal state", err)
}

go func() {
Expand Down
38 changes: 37 additions & 1 deletion internal/pkg/communication/communication.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package communication

import (
"fmt"
"sync"
"time"

"github.com/briandowns/spinner"
Expand All @@ -14,15 +15,19 @@ import (

var colorableOutput = colorable.NewColorableStdout()
var loader = spinner.New(spinner.CharSets[9], 100*time.Millisecond, spinner.WithWriter(colorableOutput))
var MessageMutex sync.Mutex

func PrintWelcomeMessage() {
MessageMutex.Lock()
fmt.Fprint(colorableOutput, aurora.Cyan("Loophole"))
fmt.Fprint(colorableOutput, aurora.Italic(" - End to end TLS encrypted TCP communication between you and your clients"))
NewLine()
NewLine()
MessageMutex.Unlock()
}

func PrintTunnelSuccessMessage(siteID string, protocols []string, localAddr string, displayQR bool) {
MessageMutex.Lock()
NewLine()

if len(protocols) < 1 {
Expand Down Expand Up @@ -59,23 +64,30 @@ func PrintTunnelSuccessMessage(siteID string, protocols []string, localAddr stri
Write("Logs:")

log.Info().Msg("Awaiting connections...")
MessageMutex.Unlock()
}

func PrintGoodbyeMessage() {
MessageMutex.Lock()
NewLine()
Write("Goodbye")
MessageMutex.Unlock()
}

func PrintFeedbackMessage(feedbackFormURL string) {
fmt.Println(aurora.Cyan(fmt.Sprintf("Thank you for using Loophole. Please give us your feedback via %s and help us improve our services.", feedbackFormURL)))
MessageMutex.Lock()
fmt.Fprintln(colorableOutput, aurora.Cyan(fmt.Sprintf("Thank you for using Loophole. Please give us your feedback via %s and help us improve our services.", feedbackFormURL)))
MessageMutex.Unlock()
}

func StartLoading(message string) {
if el := log.Debug(); !el.Enabled() {
loader.Prefix = fmt.Sprintf("%s ", message)
loader.Start()
} else {
MessageMutex.Lock()
Write(message)
MessageMutex.Unlock()
}
}

Expand All @@ -93,6 +105,30 @@ func LoadingFailure() {
}
}

func LogInfo(message string) {
MessageMutex.Lock()
log.Info().Msg(message)
MessageMutex.Unlock()
}

func LogFatalErr(message string, err error) {
MessageMutex.Lock()
log.Fatal().Err(err).Msg(message)
MessageMutex.Unlock()
}

func LogFatalMsg(message string) {
MessageMutex.Lock()
log.Fatal().Msg(message)
MessageMutex.Unlock()
}

func LogDebug(message string) {
MessageMutex.Lock()
log.Debug().Msg(message)
MessageMutex.Unlock()
}

func NewLine() {
fmt.Fprintln(colorableOutput)
}
Expand Down
Loading

0 comments on commit 721c5e7

Please sign in to comment.