initial commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type roleKey struct{}
|
||||
|
||||
type Role int
|
||||
|
||||
const (
|
||||
RoleReader Role = iota
|
||||
RoleWriter
|
||||
RoleAdmin
|
||||
)
|
||||
|
||||
func ParseRole(s string) Role {
|
||||
switch s {
|
||||
case "admin":
|
||||
return RoleAdmin
|
||||
case "writer":
|
||||
return RoleWriter
|
||||
default:
|
||||
return RoleReader
|
||||
}
|
||||
}
|
||||
|
||||
func (r Role) CanRead() bool { return true }
|
||||
func (r Role) CanWrite() bool { return r >= RoleWriter }
|
||||
func (r Role) CanDDL() bool { return r >= RoleAdmin }
|
||||
|
||||
type Handler struct {
|
||||
role Role
|
||||
}
|
||||
|
||||
func New(roleStr string) *Handler {
|
||||
return &Handler{role: ParseRole(roleStr)}
|
||||
}
|
||||
|
||||
func (h *Handler) Middleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.WithValue(r.Context(), roleKey{}, h.role)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
func RoleFromContext(ctx context.Context) Role {
|
||||
if r, ok := ctx.Value(roleKey{}).(Role); ok {
|
||||
return r
|
||||
}
|
||||
return RoleReader
|
||||
}
|
||||
|
||||
func RequireWrite(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if !RoleFromContext(r.Context()).CanWrite() {
|
||||
http.Error(w, `{"error":"forbidden: write access required"}`, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func RequireDDL(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if !RoleFromContext(r.Context()).CanDDL() {
|
||||
http.Error(w, `{"error":"forbidden: admin access required"}`, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func RequireWriteMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !RoleFromContext(r.Context()).CanWrite() {
|
||||
http.Error(w, `{"error":"forbidden: write access required"}`, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user