diff options
author | Brian Picciano <mediocregopher@gmail.com> | 2022-05-20 14:54:26 -0600 |
---|---|---|
committer | Brian Picciano <mediocregopher@gmail.com> | 2022-05-20 14:54:26 -0600 |
commit | 1ffda21ae38d203e381bedbf7bdbbd69c9031062 (patch) | |
tree | 32b28a8fd92341e69f639b6959bfd04347728494 /srv/src/http/auth.go | |
parent | ae1fa76efc0d771ca50dede367bd228ce9f7b969 (diff) |
Implement ratelimit on authentications
Diffstat (limited to 'srv/src/http/auth.go')
-rw-r--r-- | srv/src/http/auth.go | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/srv/src/http/auth.go b/srv/src/http/auth.go index cd247a3..9527cc8 100644 --- a/srv/src/http/auth.go +++ b/srv/src/http/auth.go @@ -1,7 +1,9 @@ package http import ( + "context" "net/http" + "time" "github.com/mediocregopher/blog.mediocregopher.com/srv/http/apiutil" "golang.org/x/crypto/bcrypt" @@ -19,21 +21,37 @@ func NewPasswordHash(plaintext string) string { // Auther determines who can do what. type Auther interface { - Allowed(username, password string) bool + Allowed(ctx context.Context, username, password string) bool + Close() error } type auther struct { - users map[string]string + users map[string]string + ticker *time.Ticker } // NewAuther initializes and returns an Auther will which allow the given // username and password hash combinations. Password hashes must have been // created using NewPasswordHash. -func NewAuther(users map[string]string) Auther { - return &auther{users: users} +func NewAuther(users map[string]string, ratelimit time.Duration) Auther { + return &auther{ + users: users, + ticker: time.NewTicker(ratelimit), + } +} + +func (a *auther) Close() error { + a.ticker.Stop() + return nil } -func (a *auther) Allowed(username, password string) bool { +func (a *auther) Allowed(ctx context.Context, username, password string) bool { + + select { + case <-ctx.Done(): + return false + case <-a.ticker.C: + } hashedPassword, ok := a.users[username] if !ok { @@ -64,7 +82,7 @@ func authMiddleware(auther Auther, h http.Handler) http.Handler { return } - if !auther.Allowed(username, password) { + if !auther.Allowed(r.Context(), username, password) { respondUnauthorized(rw, r) return } |