Skip to content

Commit 61ad744

Browse files
committed
feat(ssh): use custom logging middleware
1 parent b26060b commit 61ad744

File tree

7 files changed

+85
-39
lines changed

7 files changed

+85
-39
lines changed

server/git/errors.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package git
2+
3+
import "errors"
4+
5+
var (
6+
// ErrNotAuthed represents unauthorized access.
7+
ErrNotAuthed = errors.New("you are not authorized to do this")
8+
9+
// ErrSystemMalfunction represents a general system error returned to clients.
10+
ErrSystemMalfunction = errors.New("something went wrong")
11+
12+
// ErrInvalidRepo represents an attempt to access a non-existent repo.
13+
ErrInvalidRepo = errors.New("invalid repo")
14+
15+
// ErrInvalidRequest represents an invalid request.
16+
ErrInvalidRequest = errors.New("invalid request")
17+
18+
// ErrMaxConnections represents a maximum connection limit being reached.
19+
ErrMaxConnections = errors.New("too many connections, try again later")
20+
21+
// ErrTimeout is returned when the maximum read timeout is exceeded.
22+
ErrTimeout = errors.New("I/O timeout reached")
23+
)

server/git/git.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package git
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"io"
87
"path/filepath"
@@ -14,27 +13,6 @@ import (
1413
gitm "github.com/gogs/git-module"
1514
)
1615

17-
var (
18-
19-
// ErrNotAuthed represents unauthorized access.
20-
ErrNotAuthed = errors.New("you are not authorized to do this")
21-
22-
// ErrSystemMalfunction represents a general system error returned to clients.
23-
ErrSystemMalfunction = errors.New("something went wrong")
24-
25-
// ErrInvalidRepo represents an attempt to access a non-existent repo.
26-
ErrInvalidRepo = errors.New("invalid repo")
27-
28-
// ErrInvalidRequest represents an invalid request.
29-
ErrInvalidRequest = errors.New("invalid request")
30-
31-
// ErrMaxConnections represents a maximum connection limit being reached.
32-
ErrMaxConnections = errors.New("too many connections, try again later")
33-
34-
// ErrTimeout is returned when the maximum read timeout is exceeded.
35-
ErrTimeout = errors.New("I/O timeout reached")
36-
)
37-
3816
// WritePktline encodes and writes a pktline to the given writer.
3917
func WritePktline(w io.Writer, v ...interface{}) error {
4018
msg := fmt.Sprintln(v...)

server/git/service.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"os/exec"
1010
"strings"
1111

12-
"github.com/charmbracelet/log"
1312
"golang.org/x/sync/errgroup"
1413
)
1514

@@ -112,7 +111,6 @@ func gitServiceHandler(ctx context.Context, svc Service, scmd ServiceCommand) er
112111
}
113112
}
114113

115-
log.Debugf("git service command in %q: %s", cmd.Dir, cmd.String())
116114
if err := cmd.Start(); err != nil {
117115
if errors.Is(err, os.ErrNotExist) {
118116
return ErrInvalidRepo

server/ssh/cmd/git.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,17 @@ func gitRunE(cmd *cobra.Command, args []string) error {
209209

210210
repoPath := filepath.Join(reposDir, repoDir)
211211
service := git.Service(cmd.Name())
212+
stdin := cmd.InOrStdin()
213+
stdout := cmd.OutOrStdout()
214+
stderr := cmd.ErrOrStderr()
212215
scmd := git.ServiceCommand{
213-
Stdin: cmd.InOrStdin(),
214-
Stdout: s,
215-
Stderr: s.Stderr(),
216+
Stdin: stdin,
217+
Stdout: stdout,
218+
Stderr: stderr,
216219
Env: envs,
217220
Dir: repoPath,
218221
}
219222

220-
logger.Debug("git middleware", "cmd", service, "access", accessLevel.String())
221-
222223
switch service {
223224
case git.ReceivePackService:
224225
receivePackCounter.WithLabelValues(name).Inc()
@@ -237,16 +238,19 @@ func gitRunE(cmd *cobra.Command, args []string) error {
237238
}
238239

239240
if err := service.Handler(ctx, scmd); err != nil {
241+
logger.Error("failed to handle git service", "service", service, "err", err, "repo", name)
240242
defer func() {
241243
if repo == nil {
242244
// If the repo was created, but the request failed, delete it.
243245
be.DeleteRepository(ctx, name) // nolint: errcheck
244246
}
245247
}()
248+
246249
return git.ErrSystemMalfunction
247250
}
248251

249252
if err := git.EnsureDefaultBranch(ctx, scmd); err != nil {
253+
logger.Error("failed to ensure default branch", "err", err, "repo", name)
250254
return git.ErrSystemMalfunction
251255
}
252256

@@ -279,7 +283,7 @@ func gitRunE(cmd *cobra.Command, args []string) error {
279283
if errors.Is(err, git.ErrInvalidRepo) {
280284
return git.ErrInvalidRepo
281285
} else if err != nil {
282-
logger.Error("git middleware", "err", err)
286+
logger.Error("failed to handle git service", "service", service, "err", err, "repo", name)
283287
return git.ErrSystemMalfunction
284288
}
285289

@@ -322,7 +326,7 @@ func gitRunE(cmd *cobra.Command, args []string) error {
322326
}
323327

324328
if err := service.Handler(ctx, scmd); err != nil {
325-
logger.Error("git middleware", "err", err)
329+
logger.Error("failed to handle lfs service", "service", service, "err", err, "repo", name)
326330
return git.ErrSystemMalfunction
327331
}
328332

server/ssh/middleware.go

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package ssh
22

33
import (
4+
"fmt"
5+
"time"
6+
47
"github.com/charmbracelet/log"
58
"github.com/charmbracelet/soft-serve/server/backend"
69
"github.com/charmbracelet/soft-serve/server/config"
@@ -49,7 +52,6 @@ func CommandMiddleware(sh ssh.Handler) ssh.Handler {
4952

5053
ctx := s.Context()
5154
cfg := config.FromContext(ctx)
52-
logger := log.FromContext(ctx)
5355

5456
args := s.Command()
5557
cliCommandCounter.WithLabelValues(cmd.CommandName(args)).Inc()
@@ -110,11 +112,56 @@ func CommandMiddleware(sh ssh.Handler) ssh.Handler {
110112
}
111113

112114
if err := rootCmd.ExecuteContext(ctx); err != nil {
113-
logger.Error("error executing command", "err", err)
114115
s.Exit(1) // nolint: errcheck
115116
return
116117
}
117118
}()
118119
sh(s)
119120
}
120121
}
122+
123+
// LoggingMiddleware logs the ssh connection and command.
124+
func LoggingMiddleware(sh ssh.Handler) ssh.Handler {
125+
return func(s ssh.Session) {
126+
ctx := s.Context()
127+
logger := log.FromContext(ctx).WithPrefix("ssh")
128+
ct := time.Now()
129+
hpk := sshutils.MarshalAuthorizedKey(s.PublicKey())
130+
ptyReq, _, isPty := s.Pty()
131+
addr := s.RemoteAddr().String()
132+
user := proto.UserFromContext(ctx)
133+
logArgs := []interface{}{
134+
"addr",
135+
addr,
136+
"cmd",
137+
s.Command(),
138+
}
139+
140+
if user != nil {
141+
logArgs = append([]interface{}{
142+
"username",
143+
user.Username(),
144+
}, logArgs...)
145+
}
146+
147+
if isPty {
148+
logArgs = []interface{}{
149+
"term", ptyReq.Term,
150+
"width", ptyReq.Window.Width,
151+
"height", ptyReq.Window.Height,
152+
}
153+
}
154+
155+
if config.IsVerbose() {
156+
logArgs = append(logArgs,
157+
"key", hpk,
158+
"envs", s.Environ(),
159+
)
160+
}
161+
162+
msg := fmt.Sprintf("user %q", s.User())
163+
logger.Debug(msg+" connected", logArgs...)
164+
sh(s)
165+
logger.Debug(msg+" disconnected", append(logArgs, "duration", time.Since(ct))...)
166+
}
167+
}

server/ssh/ssh.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/charmbracelet/ssh"
1919
"github.com/charmbracelet/wish"
2020
bm "github.com/charmbracelet/wish/bubbletea"
21-
lm "github.com/charmbracelet/wish/logging"
2221
rm "github.com/charmbracelet/wish/recover"
2322
"github.com/muesli/termenv"
2423
"github.com/prometheus/client_golang/prometheus"
@@ -74,12 +73,10 @@ func NewSSHServer(ctx context.Context) (*SSHServer, error) {
7473
bm.MiddlewareWithProgramHandler(SessionHandler, termenv.ANSI256),
7574
// CLI middleware.
7675
CommandMiddleware,
76+
// Logging middleware.
77+
LoggingMiddleware,
7778
// Context middleware.
7879
ContextMiddleware(cfg, dbx, datastore, be, logger),
79-
// Logging middleware.
80-
lm.MiddlewareWithLogger(
81-
&loggerAdapter{logger, log.DebugLevel},
82-
),
8380
),
8481
}
8582

server/web/git.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ var (
7575
func withParams(h http.Handler) http.Handler {
7676
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
7777
ctx := r.Context()
78-
logger := log.FromContext(ctx)
7978
cfg := config.FromContext(ctx)
8079
vars := mux.Vars(r)
8180
repo := vars["repo"]

0 commit comments

Comments
 (0)