introduce REST API authorization.

This commit is contained in:
Miroslav Šedivý 2020-11-16 19:37:52 +01:00
parent 316533dab0
commit 0dab2a99d3
3 changed files with 64 additions and 18 deletions

View File

@ -4,6 +4,7 @@ import (
"github.com/go-chi/chi"
"demodesk/neko/internal/types"
"demodesk/neko/internal/http/auth"
)
type RoomHandler struct {
@ -27,15 +28,14 @@ func New(
}
func (h *RoomHandler) Route(r chi.Router) {
// TODO: Authorizaton.
r.Route("/screen", func(r chi.Router) {
r.Get("/", h.ScreenConfiguration)
r.Post("/", h.ScreenConfigurationChange)
r.Get("/configurations", h.ScreenConfigurationsList)
r.With(auth.AdminsOnly).Post("/", h.ScreenConfigurationChange)
r.With(auth.AdminsOnly).Get("/configurations", h.ScreenConfigurationsList)
})
r.Route("/clipboard", func(r chi.Router) {
r.With(auth.HostsOnly).Route("/clipboard", func(r chi.Router) {
r.Get("/", h.ClipboardRead)
r.Post("/", h.ClipboardWrite)
})

View File

@ -1,13 +1,13 @@
package api
import (
"context"
"net/http"
"github.com/go-chi/chi"
"demodesk/neko/internal/api/member"
"demodesk/neko/internal/api/room"
"demodesk/neko/internal/http/auth"
"demodesk/neko/internal/types"
"demodesk/neko/internal/utils"
"demodesk/neko/internal/config"
@ -19,12 +19,6 @@ type ApiManagerCtx struct {
capture types.CaptureManager
}
type key int
const (
keySessionCtx key = iota
)
func New(
sessions types.SessionManager,
desktop types.DesktopManager,
@ -49,7 +43,7 @@ func (api *ApiManagerCtx) Route(r chi.Router) {
r.Route("/room", roomHandler.Route)
r.Get("/test", func(w http.ResponseWriter, r *http.Request) {
session := GetSession(r)
session := auth.GetSession(r)
utils.HttpBadRequest(w, "Hi `" + session.ID() + "`, you are authenticated.")
})
}
@ -60,12 +54,7 @@ func (api *ApiManagerCtx) Authenticate(next http.Handler) http.Handler {
if err != nil {
utils.HttpNotAuthenticated(w, err)
} else {
ctx := context.WithValue(r.Context(), keySessionCtx, session)
next.ServeHTTP(w, r.WithContext(ctx))
next.ServeHTTP(w, auth.SetSession(r, session))
}
})
}
func GetSession(r *http.Request) types.Session {
return r.Context().Value(keySessionCtx).(types.Session)
}

View File

@ -0,0 +1,57 @@
package auth
import (
"context"
"net/http"
"demodesk/neko/internal/types"
"demodesk/neko/internal/utils"
)
type key int
const (
keySessionCtx key = iota
)
func SetSession(r *http.Request, session types.Session) *http.Request {
ctx := context.WithValue(r.Context(), keySessionCtx, session)
return r.WithContext(ctx)
}
func GetSession(r *http.Request) types.Session {
return r.Context().Value(keySessionCtx).(types.Session)
}
func AdminsOnly(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := GetSession(r)
if !session.Admin() {
utils.HttpNotAuthorized(w)
} else {
next.ServeHTTP(w, r)
}
})
}
func HostsOnly(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := GetSession(r)
if !session.IsHost() {
utils.HttpNotAuthorized(w, "Only host can do this.")
} else {
next.ServeHTTP(w, r)
}
})
}
func HostsOrAdminsOnly(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := GetSession(r)
if !session.IsHost() && !session.Admin() {
utils.HttpNotAuthorized(w, "Only host can do this.")
} else {
next.ServeHTTP(w, r)
}
})
}