package sshx import ( "context" "errors" "fmt" "os" "github.com/barerepo/server/internal/gitx" "github.com/barerepo/server/internal/hook" "github.com/barerepo/server/internal/transport" ) // Serve decides whether this named account may do this, then hands git the connection. func Serve(ctx context.Context, t *transport.Server, account, cmd string) error { r, err := Parse(cmd) if err != nil { return err } intent := transport.Read if r.Write() { // ssh runs one receive-pack per push, so there is no advertise to hold creation back from. intent = transport.Write } res, err := t.Open(ctx, r.Owner, r.Name, account, intent) var moved transport.Redirect switch { case errors.As(err, &moved): // ssh has no redirect, so say where it went and what to run about it. user := t.Cfg.Server.SSHUser if user == "" { user = "git" } return fmt.Errorf("%s/%s moved to %s/%s. update your remote:\n"+ " git remote set-url origin %s@%s:%s/%s", r.Owner, r.Name, moved.Owner, moved.Name, user, t.Cfg.Server.SSHHost, moved.Owner, moved.Name) case err != nil: return err } if res.Warning != "" { fmt.Fprintln(os.Stderr, res.Warning) } env := hook.Env{ Account: account, Owner: res.Owner, Name: res.Name, Dir: res.Dir, Created: res.Created, URL: t.Cfg.Server.ExternalURL + "/" + res.Owner + "/" + res.Name, Config: t.Cfg.Path, } verb := r.Verb[len("git-"):] return gitx.Pipe(ctx, res.Dir, os.Stdin, os.Stdout, os.Stderr, env.Vars(), verb, ".") }