package caddy_tailscale import ( "encoding/json" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth" "github.com/caddyserver/caddy/v2/modules/caddyhttp/headers" "net/http" ) func init() { httpcaddyfile.RegisterDirective("tailscale_auth", parseCaddyfileTSAuth) httpcaddyfile.RegisterDirectiveOrder("tailscale_auth", httpcaddyfile.After, "basic_auth") } // parseCaddyfileTSAuth sets up the handler from Caddyfile tokens. Syntax: // // tailscale_auth // // See also for further examples: https://github.com/caddyserver/caddy/blob/master/modules/caddyhttp/caddyauth/caddyfile.go func parseCaddyfileTSAuth(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) { h.Next() // consume directive name handlers := []json.RawMessage{ caddyconfig.JSONModuleObject( caddyauth.Authentication{ ProvidersRaw: caddy.ModuleMap{ "tailscale": caddyconfig.JSON(new(TailscaleAuth), nil), }, }, "handler", "authentication", nil, ), } if h.Next() { if h.Val() == "set_headers" { handlers = append(handlers, caddyconfig.JSONModuleObject( &headers.Handler{ Request: &headers.HeaderOps{ Set: http.Header{ "X-Tailscale-ID": []string{"{http.auth.user.id}"}, "X-Tailscale-Display-Name": []string{"{http.auth.user.display_name}"}, "X-Tailscale-Login-Name": []string{"{http.auth.user.login_name}"}, }, }, }, "handler", "headers", nil, )) } else { return nil, h.Errf("unknown argument %#v", h.ValRaw()) } } if h.NextArg() { return nil, h.Err("too many arguments") } return []httpcaddyfile.ConfigValue{ { Class: "route", Value: caddyhttp.Route{ HandlersRaw: handlers, }, }, }, nil }