Skip to content

Commit

Permalink
throttle new registrations
Browse files Browse the repository at this point in the history
  • Loading branch information
dimkr committed Nov 1, 2023
1 parent 73e4488 commit e0ebcb9
Show file tree
Hide file tree
Showing 5 changed files with 789 additions and 3 deletions.
4 changes: 2 additions & 2 deletions front/gemini/gemini.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func getUser(ctx context.Context, db *sql.DB, conn net.Conn, tlsConn *tls.Conn,
return &actor, nil
}

func handle(ctx context.Context, handler front.Handler, conn net.Conn, db *sql.DB, resolver *fed.Resolver, wg *sync.WaitGroup, log *slog.Logger) {
func Handle(ctx context.Context, handler front.Handler, conn net.Conn, db *sql.DB, resolver *fed.Resolver, wg *sync.WaitGroup, log *slog.Logger) {
if err := conn.SetDeadline(time.Now().Add(reqTimeout)); err != nil {
log.Warn("Failed to set deadline", "error", err)
return
Expand Down Expand Up @@ -187,7 +187,7 @@ func ListenAndServe(ctx context.Context, log *slog.Logger, db *sql.DB, handler f

wg.Add(1)
go func() {
handle(requestCtx, handler, conn, db, resolver, &wg, log)
Handle(requestCtx, handler, conn, db, resolver, &wg, log)
conn.Close()
timer.Stop()
cancelRequest()
Expand Down
20 changes: 20 additions & 0 deletions front/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ package front
import (
"crypto/sha256"
"crypto/tls"
"database/sql"
"fmt"
"github.com/dimkr/tootik/cfg"
"github.com/dimkr/tootik/front/text"
"github.com/dimkr/tootik/front/user"
"net/url"
"regexp"
"time"
)

const registrationInterval = time.Hour

var userNameRegex = regexp.MustCompile(`^[a-zA-Z0-9-_]{4,32}$`)

func register(w text.Writer, r *request) {
Expand Down Expand Up @@ -103,6 +107,22 @@ func register(w text.Writer, r *request) {
return
}

var lastRegister sql.NullInt64
if err := r.QueryRow(`select max(inserted) from persons where host = ?`, cfg.Domain).Scan(&lastRegister); err != nil {
r.Log.Warn("Failed to check last registration time", "name", userName, "error", err)
w.Error()
return
}

if lastRegister.Valid {
now := time.Now()
elapsed := now.Sub(time.Unix(lastRegister.Int64, 0))
if elapsed < registrationInterval {
w.Statusf(40, "Registration is closed for %s", (registrationInterval - elapsed).Truncate(time.Second).String())
return
}
}

r.Log.Info("Creating new user", "name", userName)

if _, err := user.Create(r.Context, r.DB, fmt.Sprintf("https://%s/user/%s", cfg.Domain, userName), userName, certHash); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion front/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func getUsersGraph(r *request) string {
func getInstancesGraph(r *request) string {
keys := make([]string, 7)
values := make([]int64, 7)
return getGraph(r, `select strftime('%Y-%m-%d', datetime(days.day, 'unixepoch')), count(*) from (select substr(substr(persons.id, 9), 1, instr(substr(persons.id, 9), '/')-1) as host, min(inserted/(60*60*24)*60*60*24) as day from persons group by host) hosts join (select distinct inserted/(60*60*24)*60*60*24 as day from persons where inserted>unixepoch()-60*60*24*7 and inserted<unixepoch()/(60*60*24)*60*60*24) days on hosts.day < days.day group by days.day`, keys, values)
return getGraph(r, `select strftime('%Y-%m-%d', datetime(days.day, 'unixepoch')), count(*) from (select host, min(inserted/(60*60*24)*60*60*24) as day from persons group by host) hosts join (select distinct inserted/(60*60*24)*60*60*24 as day from persons where inserted>unixepoch()-60*60*24*7 and inserted<unixepoch()/(60*60*24)*60*60*24) days on hosts.day < days.day group by days.day`, keys, values)
}

func getActiveUsersGraph(r *request) string {
Expand Down
18 changes: 18 additions & 0 deletions migrations/009_host.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package migrations

import (
"context"
"database/sql"
)

func host(ctx context.Context, tx *sql.Tx) error {
if _, err := tx.ExecContext(ctx, `ALTER TABLE persons ADD COLUMN host TEXT AS (substr(substr(id, 9), 0, instr(substr(id, 9), '/')))`); err != nil {
return err
}

if _, err := tx.ExecContext(ctx, `CREATE INDEX personshost on persons(host)`); err != nil {
return err
}

return nil
}
Loading

0 comments on commit e0ebcb9

Please sign in to comment.