fleet/server/handler.go
2016-09-05 16:03:58 -04:00

296 lines
6.6 KiB
Go

package server
import (
"net/http"
"strings"
kitlog "github.com/go-kit/kit/log"
kithttp "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
"github.com/kolide/kolide-ose/kolide"
"golang.org/x/net/context"
)
func attachAPIRoutes(router *mux.Router, ctx context.Context, svc kolide.Service, opts []kithttp.ServerOption) {
router.Handle("/api/v1/kolide/users",
kithttp.NewServer(
ctx,
mustBeAdmin(makeCreateUserEndpoint(svc)),
decodeCreateUserRequest,
encodeResponse,
opts...,
),
).Methods("POST")
router.Handle("/api/v1/kolide/users/{id}",
kithttp.NewServer(
ctx,
canReadUser(makeGetUserEndpoint(svc)),
decodeGetUserRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/users/{id}/password",
kithttp.NewServer(
ctx,
canModifyUser(makeChangePasswordEndpoint(svc)),
decodeChangePasswordRequest,
encodeResponse,
opts...,
),
).Methods("POST")
router.Handle("/api/v1/kolide/users/{id}/role",
kithttp.NewServer(
ctx,
mustBeAdmin(makeUpdateAdminRoleEndpoint(svc)),
decodeUpdateAdminRoleRequest,
encodeResponse,
opts...,
),
).Methods("POST")
router.Handle("/api/v1/kolide/users/{id}/status",
kithttp.NewServer(
ctx,
canModifyUser(makeUpdateUserStatusEndpoint(svc)),
decodeUpdateUserStatusRequest,
encodeResponse,
opts...,
),
).Methods("POST")
router.Handle("/api/v1/kolide/users/{id}/sessions",
kithttp.NewServer(
ctx,
canReadUser(makeGetInfoAboutSessionsForUserEndpoint(svc)),
decodeGetInfoAboutSessionsForUserRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/users/{id}/sessions",
kithttp.NewServer(
ctx,
canModifyUser(makeDeleteSessionsForUserEndpoint(svc)),
decodeDeleteSessionsForUserRequest,
encodeResponse,
opts...,
),
).Methods("DELETE")
router.Handle("/api/v1/kolide/sessions/{id}",
kithttp.NewServer(
ctx,
mustBeAdmin(makeGetInfoAboutSessionEndpoint(svc)),
decodeGetInfoAboutSessionRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/sessions/{id}",
kithttp.NewServer(
ctx,
mustBeAdmin(makeDeleteSessionEndpoint(svc)),
decodeDeleteSessionRequest,
encodeResponse,
opts...,
),
).Methods("DELETE")
router.Handle("/api/v1/kolide/queries/{id}",
kithttp.NewServer(
ctx,
makeGetQueryEndpoint(svc),
decodeGetQueryRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/queries",
kithttp.NewServer(
ctx,
makeGetAllQueriesEndpoint(svc),
decodeNoParamsRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/queries",
kithttp.NewServer(
ctx,
makeCreateQueryEndpoint(svc),
decodeCreateQueryRequest,
encodeResponse,
opts...,
),
).Methods("POST")
router.Handle("/api/v1/kolide/queries/{id}",
kithttp.NewServer(
ctx,
makeModifyQueryEndpoint(svc),
decodeModifyQueryRequest,
encodeResponse,
opts...,
),
).Methods("PATCH")
router.Handle("/api/v1/kolide/queries/{id}",
kithttp.NewServer(
ctx,
makeDeleteQueryEndpoint(svc),
decodeDeleteQueryRequest,
encodeResponse,
opts...,
),
).Methods("DELETE")
router.Handle("/api/v1/kolide/packs/{id}",
kithttp.NewServer(
ctx,
makeGetPackEndpoint(svc),
decodeGetPackRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/packs",
kithttp.NewServer(
ctx,
makeGetAllPacksEndpoint(svc),
decodeNoParamsRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/packs",
kithttp.NewServer(
ctx,
makeCreatePackEndpoint(svc),
decodeCreatePackRequest,
encodeResponse,
opts...,
),
).Methods("POST")
router.Handle("/api/v1/kolide/packs/{id}",
kithttp.NewServer(
ctx,
makeModifyPackEndpoint(svc),
decodeModifyPackRequest,
encodeResponse,
opts...,
),
).Methods("PATCH")
router.Handle("/api/v1/kolide/packs/{id}",
kithttp.NewServer(
ctx,
makeDeletePackEndpoint(svc),
decodeDeletePackRequest,
encodeResponse,
opts...,
),
).Methods("DELETE")
router.Handle("/api/v1/kolide/packs/{pid}/queries/{qid}",
kithttp.NewServer(
ctx,
makeAddQueryToPackEndpoint(svc),
decodeAddQueryToPackRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/packs/{id}/queries",
kithttp.NewServer(
ctx,
makeGetQueriesInPackEndpoint(svc),
decodeGetQueriesInPackRequest,
encodeResponse,
opts...,
),
).Methods("GET")
router.Handle("/api/v1/kolide/packs/{pid}/queries/{qid}",
kithttp.NewServer(
ctx,
makeDeleteQueryFromPackEndpoint(svc),
decodeDeleteQueryFromPackRequest,
encodeResponse,
opts...,
),
).Methods("DELETE")
}
// MakeHandler creates an http handler for the Kolide API
func MakeHandler(ctx context.Context, svc kolide.Service, logger kitlog.Logger) http.Handler {
opts := []kithttp.ServerOption{
kithttp.ServerBefore(
setViewerContext(svc, logger),
),
kithttp.ServerErrorLogger(logger),
kithttp.ServerAfter(
kithttp.SetContentType("application/json; charset=utf-8"),
),
}
api := mux.NewRouter()
attachAPIRoutes(api, ctx, svc, opts)
r := mux.NewRouter()
r.PathPrefix("/api/v1/kolide").Handler(authMiddleware(svc, logger, api))
r.Handle("/api/login", login(svc, logger)).Methods("POST")
r.Handle("/api/logout", logout(svc, logger)).Methods("GET")
r.PathPrefix("/assets").Handler(http.StripPrefix("/assets", http.FileServer(newBinaryFileSystem("/build"))))
for _, route := range frontendRoutes {
r.HandleFunc(route, serveReactApp)
}
return r
}
// setViewerContext updates the context with a viewerContext,
// which holds the currently logged in user
func setViewerContext(svc kolide.Service, logger kitlog.Logger) kithttp.RequestFunc {
return func(ctx context.Context, r *http.Request) context.Context {
sm := svc.NewSessionManager(ctx, nil, r)
session, err := sm.Session()
if err != nil {
logger.Log("err", err, "error-source", "setViewerContext")
return ctx
}
user, err := svc.User(ctx, session.UserID)
if err != nil {
logger.Log("err", err, "error-source", "setViewerContext")
return ctx
}
ctx = context.WithValue(ctx, "viewerContext", &viewerContext{
user: user,
})
logger.Log("msg", "viewer context set", "user", user.ID)
// get the user-id for request
if strings.Contains(r.URL.Path, "users/") {
ctx = withUserIDFromRequest(r, ctx)
}
return ctx
}
}
func withUserIDFromRequest(r *http.Request, ctx context.Context) context.Context {
id, _ := idFromRequest(r, "id")
return context.WithValue(ctx, "request-id", id)
}