guard: supress logging #745

closed
opened by oppi.li targeting master from push-ykxtvrlpxwrl

the default slog logger caused indigo/identity to emit logs when resolving identities. using a bespoke logger in the guard subcommand fixes this.

Signed-off-by: oppiliappan me@oppi.li

Changed files
+26 -29
guard
+26 -29
guard/guard.go
···
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/urfave/cli/v3"
"tangled.org/core/idresolver"
-
"tangled.org/core/log"
)
func Command() *cli.Command {
···
}
func Run(ctx context.Context, cmd *cli.Command) error {
-
l := log.FromContext(ctx)
-
incomingUser := cmd.String("user")
gitDir := cmd.String("git-dir")
logPath := cmd.String("log-path")
endpoint := cmd.String("internal-api")
motdFile := cmd.String("motd-file")
logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
-
if err != nil {
-
l.Error("failed to open log file", "error", err)
-
return err
-
} else {
-
fileHandler := slog.NewJSONHandler(logFile, &slog.HandlerOptions{Level: slog.LevelInfo})
-
l = slog.New(fileHandler)
}
var clientIP string
if connInfo := os.Getenv("SSH_CONNECTION"); connInfo != "" {
parts := strings.Fields(connInfo)
···
}
if incomingUser == "" {
-
l.Error("access denied: no user specified")
fmt.Fprintln(os.Stderr, "access denied: no user specified")
os.Exit(-1)
}
sshCommand := os.Getenv("SSH_ORIGINAL_COMMAND")
-
l.Info("connection attempt",
"user", incomingUser,
"command", sshCommand,
"client", clientIP)
if sshCommand == "" {
-
l.Info("access denied: no interactive shells", "user", incomingUser)
fmt.Fprintf(os.Stderr, "Hi @%s! You've successfully authenticated.\n", incomingUser)
os.Exit(-1)
}
cmdParts := strings.Fields(sshCommand)
if len(cmdParts) < 2 {
-
l.Error("invalid command format", "command", sshCommand)
fmt.Fprintln(os.Stderr, "invalid command format")
os.Exit(-1)
}
···
// any of the above with a leading slash (/)
components := strings.Split(strings.TrimPrefix(strings.Trim(cmdParts[1], "'"), "/"), "/")
-
l.Info("command components", "components", components)
if len(components) != 2 {
-
l.Error("invalid repo format", "components", components)
fmt.Fprintln(os.Stderr, "invalid repo format, needs <user>/<repo> or /<user>/<repo>")
os.Exit(-1)
}
didOrHandle := components[0]
-
identity := resolveIdentity(ctx, l, didOrHandle)
did := identity.DID.String()
repoName := components[1]
qualifiedRepoName, _ := securejoin.SecureJoin(did, repoName)
···
"git-upload-archive": true,
}
if !validCommands[gitCommand] {
-
l.Error("access denied: invalid git command", "command", gitCommand)
fmt.Fprintln(os.Stderr, "access denied: invalid git command")
return fmt.Errorf("access denied: invalid git command")
}
if gitCommand != "git-upload-pack" {
-
if !isPushPermitted(l, incomingUser, qualifiedRepoName, endpoint) {
-
l.Error("access denied: user not allowed",
"did", incomingUser,
"reponame", qualifiedRepoName)
fmt.Fprintln(os.Stderr, "access denied: user not allowed")
···
fullPath, _ := securejoin.SecureJoin(gitDir, qualifiedRepoName)
-
l.Info("processing command",
"user", incomingUser,
"command", gitCommand,
"repo", repoName,
···
var motdReader io.Reader
if reader, err := os.Open(motdFile); err != nil {
if !errors.Is(err, os.ErrNotExist) {
-
l.Error("failed to read motd file", "error", err)
}
motdReader = strings.NewReader("Welcome to this knot!\n")
} else {
···
)
if err := gitCmd.Run(); err != nil {
-
l.Error("command failed", "error", err)
fmt.Fprintf(os.Stderr, "command failed: %v\n", err)
return fmt.Errorf("command failed: %v", err)
}
-
l.Info("command completed",
"user", incomingUser,
"command", gitCommand,
"repo", repoName,
···
return nil
}
-
func resolveIdentity(ctx context.Context, l *slog.Logger, didOrHandle string) *identity.Identity {
resolver := idresolver.DefaultResolver()
ident, err := resolver.ResolveIdent(ctx, didOrHandle)
if err != nil {
-
l.Error("Error resolving handle", "error", err, "handle", didOrHandle)
fmt.Fprintf(os.Stderr, "error resolving handle: %v\n", err)
os.Exit(1)
}
if ident.Handle.IsInvalidHandle() {
-
l.Error("Error resolving handle", "invalid handle", didOrHandle)
fmt.Fprintf(os.Stderr, "error resolving handle: invalid handle\n")
os.Exit(1)
}
return ident
}
-
func isPushPermitted(l *slog.Logger, user, qualifiedRepoName, endpoint string) bool {
u, _ := url.Parse(endpoint + "/push-allowed")
q := u.Query()
q.Add("user", user)
···
req, err := http.Get(u.String())
if err != nil {
-
l.Error("Error verifying permissions", "error", err)
fmt.Fprintf(os.Stderr, "error verifying permissions: %v\n", err)
os.Exit(1)
}
-
l.Info("Checking push permission",
"url", u.String(),
"status", req.Status)
···
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/urfave/cli/v3"
"tangled.org/core/idresolver"
)
func Command() *cli.Command {
···
}
func Run(ctx context.Context, cmd *cli.Command) error {
incomingUser := cmd.String("user")
gitDir := cmd.String("git-dir")
logPath := cmd.String("log-path")
endpoint := cmd.String("internal-api")
motdFile := cmd.String("motd-file")
+
stream := io.Discard
logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+
if err == nil {
+
stream = logFile
}
+
fileHandler := slog.NewJSONHandler(stream, &slog.HandlerOptions{Level: slog.LevelInfo})
+
slog.SetDefault(slog.New(fileHandler))
+
var clientIP string
if connInfo := os.Getenv("SSH_CONNECTION"); connInfo != "" {
parts := strings.Fields(connInfo)
···
}
if incomingUser == "" {
+
slog.Error("access denied: no user specified")
fmt.Fprintln(os.Stderr, "access denied: no user specified")
os.Exit(-1)
}
sshCommand := os.Getenv("SSH_ORIGINAL_COMMAND")
+
slog.Info("connection attempt",
"user", incomingUser,
"command", sshCommand,
"client", clientIP)
if sshCommand == "" {
+
slog.Info("access denied: no interactive shells", "user", incomingUser)
fmt.Fprintf(os.Stderr, "Hi @%s! You've successfully authenticated.\n", incomingUser)
os.Exit(-1)
}
cmdParts := strings.Fields(sshCommand)
if len(cmdParts) < 2 {
+
slog.Error("invalid command format", "command", sshCommand)
fmt.Fprintln(os.Stderr, "invalid command format")
os.Exit(-1)
}
···
// any of the above with a leading slash (/)
components := strings.Split(strings.TrimPrefix(strings.Trim(cmdParts[1], "'"), "/"), "/")
+
slog.Info("command components", "components", components)
if len(components) != 2 {
+
slog.Error("invalid repo format", "components", components)
fmt.Fprintln(os.Stderr, "invalid repo format, needs <user>/<repo> or /<user>/<repo>")
os.Exit(-1)
}
didOrHandle := components[0]
+
identity := resolveIdentity(ctx, didOrHandle)
did := identity.DID.String()
repoName := components[1]
qualifiedRepoName, _ := securejoin.SecureJoin(did, repoName)
···
"git-upload-archive": true,
}
if !validCommands[gitCommand] {
+
slog.Error("access denied: invalid git command", "command", gitCommand)
fmt.Fprintln(os.Stderr, "access denied: invalid git command")
return fmt.Errorf("access denied: invalid git command")
}
if gitCommand != "git-upload-pack" {
+
if !isPushPermitted(incomingUser, qualifiedRepoName, endpoint) {
+
slog.Error("access denied: user not allowed",
"did", incomingUser,
"reponame", qualifiedRepoName)
fmt.Fprintln(os.Stderr, "access denied: user not allowed")
···
fullPath, _ := securejoin.SecureJoin(gitDir, qualifiedRepoName)
+
slog.Info("processing command",
"user", incomingUser,
"command", gitCommand,
"repo", repoName,
···
var motdReader io.Reader
if reader, err := os.Open(motdFile); err != nil {
if !errors.Is(err, os.ErrNotExist) {
+
slog.Error("failed to read motd file", "error", err)
}
motdReader = strings.NewReader("Welcome to this knot!\n")
} else {
···
)
if err := gitCmd.Run(); err != nil {
+
slog.Error("command failed", "error", err)
fmt.Fprintf(os.Stderr, "command failed: %v\n", err)
return fmt.Errorf("command failed: %v", err)
}
+
slog.Info("command completed",
"user", incomingUser,
"command", gitCommand,
"repo", repoName,
···
return nil
}
+
func resolveIdentity(ctx context.Context, didOrHandle string) *identity.Identity {
resolver := idresolver.DefaultResolver()
ident, err := resolver.ResolveIdent(ctx, didOrHandle)
if err != nil {
+
slog.Error("Error resolving handle", "error", err, "handle", didOrHandle)
fmt.Fprintf(os.Stderr, "error resolving handle: %v\n", err)
os.Exit(1)
}
if ident.Handle.IsInvalidHandle() {
+
slog.Error("Error resolving handle", "invalid handle", didOrHandle)
fmt.Fprintf(os.Stderr, "error resolving handle: invalid handle\n")
os.Exit(1)
}
return ident
}
+
func isPushPermitted(user, qualifiedRepoName, endpoint string) bool {
u, _ := url.Parse(endpoint + "/push-allowed")
q := u.Query()
q.Add("user", user)
···
req, err := http.Get(u.String())
if err != nil {
+
slog.Error("Error verifying permissions", "error", err)
fmt.Fprintf(os.Stderr, "error verifying permissions: %v\n", err)
os.Exit(1)
}
+
slog.Info("checking push permission",
"url", u.String(),
"status", req.Status)