-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use fiber/middleware/keyauth as starting point (#4)
- Loading branch information
1 parent
6bcf10f
commit 977e0cc
Showing
5 changed files
with
729 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package authmeter | ||
|
||
import ( | ||
"errors" | ||
"net/url" | ||
"strings" | ||
|
||
"github.com/gofiber/fiber/v2" | ||
) | ||
|
||
// When there is no request of the key thrown ErrMissingOrMalformedAPIKey | ||
var ErrMissingOrMalformedAPIKey = errors.New("missing or malformed API Key") | ||
|
||
const ( | ||
query = "query" | ||
form = "form" | ||
param = "param" | ||
cookie = "cookie" | ||
) | ||
|
||
func New(config ...Config) fiber.Handler { | ||
// Init config | ||
cfg := configDefault(config...) | ||
|
||
// Initialize | ||
parts := strings.Split(cfg.KeyLookup, ":") | ||
extractor := keyFromHeader(parts[1], cfg.AuthScheme) | ||
switch parts[0] { | ||
case query: | ||
extractor = keyFromQuery(parts[1]) | ||
case form: | ||
extractor = keyFromForm(parts[1]) | ||
case param: | ||
extractor = keyFromParam(parts[1]) | ||
case cookie: | ||
extractor = keyFromCookie(parts[1]) | ||
} | ||
|
||
// Return middleware handler | ||
return func(c *fiber.Ctx) error { | ||
// Filter request to skip middleware | ||
if cfg.Next != nil && cfg.Next(c) { | ||
return c.Next() | ||
} | ||
|
||
// Extract and verify key | ||
key, err := extractor(c) | ||
if err != nil { | ||
return cfg.ErrorHandler(c, err) | ||
} | ||
|
||
valid, err := cfg.Validator(c, key) | ||
|
||
if err == nil && valid { | ||
c.Locals(cfg.ContextKey, key) | ||
return cfg.SuccessHandler(c) | ||
} | ||
return cfg.ErrorHandler(c, err) | ||
} | ||
} | ||
|
||
// keyFromHeader returns a function that extracts api key from the request header. | ||
func keyFromHeader(header, authScheme string) func(c *fiber.Ctx) (string, error) { | ||
return func(c *fiber.Ctx) (string, error) { | ||
auth := c.Get(header) | ||
l := len(authScheme) | ||
if len(auth) > 0 && l == 0 { | ||
return auth, nil | ||
} | ||
if len(auth) > l+1 && auth[:l] == authScheme { | ||
return auth[l+1:], nil | ||
} | ||
return "", ErrMissingOrMalformedAPIKey | ||
} | ||
} | ||
|
||
// keyFromQuery returns a function that extracts api key from the query string. | ||
func keyFromQuery(param string) func(c *fiber.Ctx) (string, error) { | ||
return func(c *fiber.Ctx) (string, error) { | ||
key := c.Query(param) | ||
if key == "" { | ||
return "", ErrMissingOrMalformedAPIKey | ||
} | ||
return key, nil | ||
} | ||
} | ||
|
||
// keyFromForm returns a function that extracts api key from the form. | ||
func keyFromForm(param string) func(c *fiber.Ctx) (string, error) { | ||
return func(c *fiber.Ctx) (string, error) { | ||
key := c.FormValue(param) | ||
if key == "" { | ||
return "", ErrMissingOrMalformedAPIKey | ||
} | ||
return key, nil | ||
} | ||
} | ||
|
||
// keyFromParam returns a function that extracts api key from the url param string. | ||
func keyFromParam(param string) func(c *fiber.Ctx) (string, error) { | ||
return func(c *fiber.Ctx) (string, error) { | ||
key, err := url.PathUnescape(c.Params(param)) | ||
if err != nil { | ||
return "", ErrMissingOrMalformedAPIKey | ||
} | ||
return key, nil | ||
} | ||
} | ||
|
||
// keyFromCookie returns a function that extracts api key from the named cookie. | ||
func keyFromCookie(name string) func(c *fiber.Ctx) (string, error) { | ||
return func(c *fiber.Ctx) (string, error) { | ||
key := c.Cookies(name) | ||
if key == "" { | ||
return "", ErrMissingOrMalformedAPIKey | ||
} | ||
return key, nil | ||
} | ||
} |
Oops, something went wrong.