Skip to content

Commit

Permalink
Replace -auth with -email-from (arp242#270)
Browse files Browse the repository at this point in the history
* Replace -auth with -email-from

Sets email address in a few more places as well.

* Exit when we can't bind to -listen
  • Loading branch information
arp242 authored May 21, 2020
1 parent e27215e commit cde0459
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 59 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ but not every minor bugfix.

The goatcounter.com service generally runs the latest master.


Unreleased
----------

- Replace `-auth` with `-email-from` (#270)

Since the email auth no longer exists the `-auth` parameter no longer makes
sense. It's now replaced with `-email-from`, which can be set to just an email
address.

- Improve performance (#265)

Increase performance by quite a bit on large sites and time ranges.


2020-05-18 v1.2.0
-----------------

Expand Down
2 changes: 1 addition & 1 deletion cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ var (
Saas bool
Serve bool
Port string
LoginFrom string
EmailFrom string
)
4 changes: 2 additions & 2 deletions cmd/goatcounter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Usage: goatcounter [command] [flags]
Commands:
help Show help; use "help <command>" or "help all" for more details.
help Show help; use "help <topic>" or "help all" for more details.
version Show version and build information and exit.
migrate Run database migrations.
create Create a new site and user.
Expand All @@ -72,7 +72,7 @@ Advanced commands:
This is generally rarely needed and mostly a development tool.
monitor Monitor for pageviews.
See "help <command>" for more details for the command.
See "help <topic>" for more details for the command.
`

var CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
Expand Down
51 changes: 23 additions & 28 deletions cmd/goatcounter/saas.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"net/mail"
"os"
"os/user"
"strings"
"time"

Expand Down Expand Up @@ -67,7 +68,7 @@ func flagServeAndSaas(v *zvalidate.Validator) (string, bool, bool, string, strin
CommandLine.StringVar(&zmail.SMTP, "smtp", "stdout", "")
tls := CommandLine.String("tls", "", "")
errors := CommandLine.String("errors", "", "")
auth := CommandLine.String("auth", "email", "")
from := CommandLine.String("email-from", "", "")

err := CommandLine.Parse(os.Args[2:])
zlog.Config.SetDebug(*debug)
Expand All @@ -85,7 +86,7 @@ func flagServeAndSaas(v *zvalidate.Validator) (string, bool, bool, string, strin
flagErrors(*errors, v)
//v.Hostname("-smtp", zmail.SMTP)

return *dbConnect, dev, *automigrate, *listen, *tls, *auth, err
return *dbConnect, dev, *automigrate, *listen, *tls, *from, err
}

func setupReload() {
Expand Down Expand Up @@ -120,7 +121,7 @@ func saas() (int, error) {
CommandLine.StringVar(&domain, "domain", "goatcounter.localhost:8081,static.goatcounter.localhost:8081", "")
CommandLine.StringVar(&stripe, "stripe", "", "")
CommandLine.StringVar(&plan, "plan", goatcounter.PlanPersonal, "")
dbConnect, dev, automigrate, listen, tls, auth, err := flagServeAndSaas(&v)
dbConnect, dev, automigrate, listen, tls, from, err := flagServeAndSaas(&v)
if err != nil {
return 1, err
}
Expand All @@ -134,7 +135,7 @@ func saas() (int, error) {
v.Include("-plan", plan, goatcounter.Plans)
flagStripe(stripe, &v)
flagDomain(domain, &v)
flagAuth(auth, &v)
flagFrom(from, &v)
if v.HasErrors() {
return 1, v
}
Expand Down Expand Up @@ -225,34 +226,28 @@ func flagErrors(errors string, v *zvalidate.Validator) {
}
}

func flagAuth(auth string, v *zvalidate.Validator) {
switch {
default:
v.Append("-auth", "invalid value")

case strings.HasPrefix(auth, "email"):
s := strings.Split(auth, ":")
var from string
if len(s) > 1 {
from = s[1]
}
if from == "" {
if cfg.Domain != "" {
from = "login@" + zhttp.RemovePort(cfg.Domain)
} else {
h, err := os.Hostname()
if err != nil {
panic("cannot get hostname for -auth parameter")
}
from = "login@" + h
func flagFrom(from string, v *zvalidate.Validator) {
if from == "" {
if cfg.Domain != "" { // saas only.
from = "support@" + zhttp.RemovePort(cfg.Domain)
} else {
u, err := user.Current()
if err != nil {
panic("cannot get user for -email-from parameter")
}
h, err := os.Hostname()
if err != nil {
panic("cannot get hostname for -email-from parameter")
}
from = fmt.Sprintf("%s@%s", u.Username, h)
}

cfg.LoginFrom = from
}

if zmail.SMTP != "stdout" {
v.Email("-auth", from, fmt.Sprintf("%q is not a valid email address", from))
}
cfg.EmailFrom = from

if zmail.SMTP != "stdout" {
v.Email("-email-from", from, fmt.Sprintf("%q is not a valid email address", from))
}
}

Expand Down
30 changes: 15 additions & 15 deletions cmd/goatcounter/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,18 @@ const serveAndSaasFlags = `
-tls Serve over tls. This is a comma-separated list with any of:
none Don't serve any TLS.
path/to/file.pem TLS certificate and keyfile, in one file.
acme Create TLS certificates with ACME, this can
acme[:cache] Create TLS certificates with ACME, this can
optionally followed by a : and a cache
directory name (default: acme-secrets).
tls Accept TLS connections on -listen.
rdr Redirect port 80.
rdr Redirect port 80 to the -listen port. ACME
verification requires the server to be
available on port 80.
Examples:
Expand All @@ -72,8 +78,7 @@ const serveAndSaasFlags = `
Default: "acme,tls,rdr", blank when -dev is given.
-smtp SMTP server, as URL (e.g. "smtp://user:pass@server"). for
sending login emails and errors (if -errors has mailto:).
-smtp SMTP server, as URL (e.g. "smtp://user:pass@server").
A special value of "stdout" means no emails will be sent and
emails will be printed to stdout only. This is the default.
Expand All @@ -86,6 +91,8 @@ const serveAndSaasFlags = `
mailtrap.io box is probably better unless you really know what
you're doing.
-email-from From: address in emails. Default: <user>@<hostname>
-errors What to do with errors; they're always printed to stderr.
mailto:to_addr[,from_addr] Email to this address; the
Expand All @@ -95,13 +102,6 @@ const serveAndSaasFlags = `
Default: not set.
-auth How to handle user authentication.
email[:from_addr] Email users login tokens. The from_addr
is optional and sets the From: address.
Default: email:login@[domain flag or hostname]
-debug Modules to debug, comma-separated or 'all' for all modules.
-automigrate Automatically run all pending migrations on startup.
Expand All @@ -118,7 +118,7 @@ func serve() (int, error) {

CommandLine.StringVar(&cfg.Port, "port", "", "")
CommandLine.StringVar(&cfg.DomainStatic, "static", "", "")
dbConnect, dev, automigrate, listen, tls, auth, err := flagServeAndSaas(&v)
dbConnect, dev, automigrate, listen, tls, from, err := flagServeAndSaas(&v)
if err != nil {
return 1, err
}
Expand All @@ -130,9 +130,9 @@ func serve() (int, error) {

if cfg.DomainStatic != "" {
if p := strings.Index(cfg.DomainStatic, ":"); p > -1 {
v.Domain("-domain", cfg.DomainStatic[:p])
v.Domain("-static", cfg.DomainStatic[:p])
} else {
v.Domain("-domain", cfg.DomainStatic)
v.Domain("-static", cfg.DomainStatic)
}
cfg.URLStatic = "//" + cfg.DomainStatic
cfg.DomainCount = cfg.DomainStatic
Expand All @@ -142,7 +142,7 @@ func serve() (int, error) {
cfg.Port = ":" + cfg.Port
}

flagAuth(auth, &v)
flagFrom(from, &v)
if v.HasErrors() {
return 1, v
}
Expand Down
2 changes: 1 addition & 1 deletion export.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func Export(ctx context.Context, fp *os.File) {

user := GetUser(ctx)
err = zmail.SendTemplate("GoatCounter export ready",
mail.Address{Name: "GoatCounter export", Address: "[email protected]"},
mail.Address{Name: "GoatCounter export", Address: cfg.EmailFrom},
[]mail.Address{{Address: user.Email}},
"email_export_done.gotxt", struct {
Site Site
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
zgo.at/tz v0.0.0-20200428173314-f4a46a753a7e
zgo.at/utils v0.0.0-20200514044306-bf7c1ff8aa0c
zgo.at/zdb v0.0.0-20200518092829-2353fffa61c0
zgo.at/zhttp v0.0.0-20200518165501-40ecbc2139a8
zgo.at/zhttp v0.0.0-20200520171239-2396be244f0c
zgo.at/zlog v0.0.0-20200427184116-582329a88e79
zgo.at/zpack v1.0.1
zgo.at/zstripe v1.0.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ zgo.at/utils v0.0.0-20200514044306-bf7c1ff8aa0c h1:GWACHp07xLc1JwEISDzITuw1U4x6+
zgo.at/utils v0.0.0-20200514044306-bf7c1ff8aa0c/go.mod h1:+PbZTy2300b/A3oAh7/vJY58X5okaK67qKnAzNKJt3k=
zgo.at/zdb v0.0.0-20200518092829-2353fffa61c0 h1:yR9QnKvTQJAkoip/d2YI5l0TX7HG/SvjYsMBVQrYEpw=
zgo.at/zdb v0.0.0-20200518092829-2353fffa61c0/go.mod h1:rHd8UyafKA8OQCesbWO909CyI4iussi0DRxrcjH5j54=
zgo.at/zhttp v0.0.0-20200518165501-40ecbc2139a8 h1:QJRs7MYjWXo6bX2asLVDffAFxUrBWC8ALADyDhcEVuw=
zgo.at/zhttp v0.0.0-20200518165501-40ecbc2139a8/go.mod h1:lnKdr+Z/u747AVwOkBKweLbFFe0yyvV2JY8NONI4XpQ=
zgo.at/zhttp v0.0.0-20200520171239-2396be244f0c h1:omWqdUgEe/hvRQYgI+ighQi2DV377h3npb5GvZApHlo=
zgo.at/zhttp v0.0.0-20200520171239-2396be244f0c/go.mod h1:lnKdr+Z/u747AVwOkBKweLbFFe0yyvV2JY8NONI4XpQ=
zgo.at/zlog v0.0.0-20200404052423-adffcc8acd57 h1:sIuh9IpccNlzMsmAvF7EPT87/Ab2XdUJHizsMxbQgM4=
zgo.at/zlog v0.0.0-20200404052423-adffcc8acd57/go.mod h1:YkLAQZjLsp1RqWHn8SJokHzXyYU+6FZjM4GNY64IKME=
zgo.at/zlog v0.0.0-20200427184116-582329a88e79 h1:oHBsncZLO7OuWkJr5Kqyo9asxTYZRZwS1CW2ERdnzOM=
Expand Down
19 changes: 15 additions & 4 deletions handlers/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -996,11 +996,22 @@ func (h backend) delete(w http.ResponseWriter, r *http.Request) error {
go func() {
defer zlog.Recover()

contact := "false"
if args.ContactMe {
var u goatcounter.User
err := u.BySite(r.Context(), site.ID)
if err != nil {
zlog.Error(err)
} else {
contact = u.Email
}
}

zmail.Send("GoatCounter deletion",
mail.Address{Name: "GoatCounter deletion", Address: "[email protected]"},
[]mail.Address{{Address: "[email protected]"}},
fmt.Sprintf(`Deleted: %s (%d): contact_me: %t; reason: %s`,
site.Code, site.ID, args.ContactMe, args.Reason))
mail.Address{Name: "GoatCounter deletion", Address: cfg.EmailFrom},
[]mail.Address{{Address: cfg.EmailFrom}},
fmt.Sprintf(`Deleted: %s (%d): contact_me: %s; reason: %s`,
site.Code, site.ID, contact, args.Reason))
}()
}
}
Expand Down
4 changes: 2 additions & 2 deletions handlers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (h user) requestReset(w http.ResponseWriter, r *http.Request) error {
defer zlog.Recover()
err = zmail.SendTemplate(
fmt.Sprintf("Password reset for %s", site.Domain()),
mail.Address{Name: "GoatCounter login", Address: cfg.LoginFrom},
mail.Address{Name: "GoatCounter login", Address: cfg.EmailFrom},
[]mail.Address{{Address: u.Email}},
"email_password_reset.gotxt", struct {
Site goatcounter.Site
Expand Down Expand Up @@ -376,7 +376,7 @@ func sendEmailVerify(site *goatcounter.Site, user *goatcounter.User) {
go func() {
defer zlog.Recover()
err := zmail.SendTemplate("Verify your email",
mail.Address{Name: "GoatCounter", Address: cfg.LoginFrom},
mail.Address{Name: "GoatCounter", Address: cfg.EmailFrom},
[]mail.Address{{Address: user.Email}},
"email_verify.gotxt", struct {
Site goatcounter.Site
Expand Down
4 changes: 2 additions & 2 deletions handlers/website.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (h website) doSignup(w http.ResponseWriter, r *http.Request) error {
defer zlog.Recover()

err := zmail.SendTemplate("Welcome to GoatCounter!",
mail.Address{Name: "GoatCounter", Address: cfg.LoginFrom},
mail.Address{Name: "GoatCounter", Address: cfg.EmailFrom},
[]mail.Address{{Address: user.Email}},
"email_welcome.gotxt", struct {
Site goatcounter.Site
Expand Down Expand Up @@ -299,7 +299,7 @@ func (h website) doForgot(w http.ResponseWriter, r *http.Request) error {
defer zlog.Recover()

err = zmail.SendTemplate("Your GoatCounter sites",
mail.Address{Name: "GoatCounter", Address: cfg.LoginFrom},
mail.Address{Name: "GoatCounter", Address: cfg.EmailFrom},
[]mail.Address{{Address: args.Email}},
"email_forgot_site.gotxt", struct {
Sites goatcounter.Sites
Expand Down
2 changes: 1 addition & 1 deletion user.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func (u *User) SendLoginMail(ctx context.Context, site *Site) {
defer zlog.Recover()

err := zmail.Send("Your login URL",
mail.Address{Name: "GoatCounter login", Address: cfg.LoginFrom},
mail.Address{Name: "GoatCounter login", Address: cfg.EmailFrom},
[]mail.Address{{Address: u.Email}},
fmt.Sprintf("Hi there,\n\nYour login URL for GoatCounter is:\n\n %s/user/login/%s\n\nGo to it to log in. This key is valid for one hour and can be used only once.\n",
site.URL(), *u.LoginRequest))
Expand Down

0 comments on commit cde0459

Please sign in to comment.