stillbox/pkg/auth/auth.go

89 lines
1.7 KiB
Go
Raw Permalink Normal View History

2024-07-29 00:29:16 -04:00
package auth
2024-07-15 10:12:53 -04:00
import (
"errors"
"net/http"
2024-11-06 20:13:46 -05:00
_ "embed"
2024-11-03 07:19:03 -05:00
"dynatron.me/x/stillbox/pkg/config"
2024-11-06 20:13:46 -05:00
"github.com/go-chi/chi/v5"
2024-07-15 10:12:53 -04:00
"github.com/go-chi/jwtauth/v5"
)
2024-08-01 01:01:08 -04:00
type UserID int
func (u *UserID) Int32Ptr() *int32 {
if u == nil {
return nil
}
i := int32(*u)
return &i
}
2024-07-29 00:47:58 -04:00
// Authenticator performs API key and user JWT authentication.
2024-07-29 00:58:32 -04:00
type Authenticator interface {
jwtAuth
apiKeyAuth
}
2024-10-22 08:39:15 -04:00
type Auth struct {
2024-08-04 09:07:31 -04:00
jwt *jwtauth.JWTAuth
cfg config.Auth
2024-07-29 00:29:16 -04:00
}
2024-07-15 10:12:53 -04:00
2024-08-04 08:55:12 -04:00
// NewAuthenticator creates a new Authenticator with the provided config.
2024-10-22 08:39:15 -04:00
func NewAuthenticator(cfg config.Auth) *Auth {
a := &Auth{
2024-08-04 09:07:31 -04:00
cfg: cfg,
2024-07-29 00:29:16 -04:00
}
a.initJWT()
return a
}
func (a *Auth) HUP(cfg *config.Config) {
a.cfg = cfg.Auth
a.initJWT()
2024-07-15 10:12:53 -04:00
}
var (
2024-07-29 00:29:16 -04:00
ErrLoginFailed = errors.New("Login failed")
ErrInternal = errors.New("Internal server error")
ErrUnauthorized = errors.New("Unauthorized")
ErrBadRequest = errors.New("Bad request")
2024-07-15 10:12:53 -04:00
)
2024-07-29 00:47:58 -04:00
// ErrorResponse writes the error and appropriate HTTP response code.
2024-07-29 00:29:16 -04:00
func ErrorResponse(w http.ResponseWriter, err error) {
switch err {
case ErrLoginFailed, ErrUnauthorized:
http.Error(w, err.Error(), http.StatusUnauthorized)
case ErrBadRequest:
http.Error(w, err.Error(), http.StatusBadRequest)
case ErrInternal:
fallthrough
default:
http.Error(w, err.Error(), http.StatusInternalServerError)
2024-07-15 10:12:53 -04:00
}
}
2024-11-06 20:13:46 -05:00
func (a *Auth) PublicRoutes(r chi.Router) {
r.Post("/api/login", a.routeAuth)
r.Get("/api/login", a.routeLogin)
}
func (a *Auth) PrivateRoutes(r chi.Router) {
r.Get("/refresh", a.routeRefresh)
}
//go:embed login.html
var loginPage []byte
func (a *Auth) routeLogin(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "text/html")
_, _ = w.Write(loginPage)
}