👮 Auth
Two middlewares. One for general user authentication and one which makes routes exclusive for admins.
package main
import (
"context"
"errors"
"fmt"
"github.com/Gebes/there/v2"
"github.com/Gebes/there/v2/header"
"github.com/Gebes/there/v2/status"
"log"
"math/rand"
)
type User struct {
Id int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Admin bool `json:"admin,omitempty"`
}
func DatabaseGetUserById(token string) (*User, error) {
if len(token) != 12 {
return nil, errors.New("no user found with that auth token")
}
return &User{
Id: rand.Int(),
Name: "Chris",
Admin: true,
}, nil
}
func main() {
router := there.NewRouter()
router.Group("/user").
Get("/", UserGet).With(UserMiddleware)
router.Group("/dashboard").
Get("/", UserGet).With(UserAdminMiddleware)
err := router.Listen(8080)
if err != nil {
log.Fatalf("Could not listen on port 8080: %v", err)
}
}
func UserGet(request there.Request) there.Response {
user, ok := request.Context().Value("user").(User)
if !ok {
return there.Error(status.UnprocessableEntity, errors.New("could not get user from context"))
}
return there.Json(status.OK, user)
}
func UserMiddleware(request there.Request, next there.Response) there.Response {
authorization := request.Headers.GetDefault(header.RequestAuthorization, "")
user, err := DatabaseGetUserById(authorization)
if err != nil {
return there.Error(status.Unauthorized, fmt.Errorf("not authorized: %w", err))
}
request.WithContext(context.WithValue(request.Context(), "user", user))
return next
}
func UserAdminMiddleware(request there.Request, next there.Response) there.Response {
authorization := request.Headers.GetDefault(header.RequestAuthorization, "")
user, err := DatabaseGetUserById(authorization)
if err != nil {
return there.Error(status.Unauthorized, fmt.Errorf("not authorized: %w", err))
}
if !user.Admin {
return there.Error(status.Forbidden, errors.New("you are not allowed to access this dashboard"))
}
request.WithContext(context.WithValue(request.Context(), "user", user))
return next
}