173 lines
8.8 KiB
Go
173 lines
8.8 KiB
Go
package api
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/args"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/database"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/utils"
|
|
)
|
|
|
|
type RequestContext struct {
|
|
DBConn *sql.DB
|
|
Args *args.Arguments
|
|
|
|
Id string
|
|
Start time.Time
|
|
|
|
TemplateData *map[string]interface{}
|
|
User *database.User
|
|
}
|
|
|
|
type Continuation func(*RequestContext, *http.Request, http.ResponseWriter) ContinuationChain
|
|
type ContinuationChain func(Continuation, Continuation) ContinuationChain
|
|
|
|
func LogRequestContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
context.Start = time.Now()
|
|
context.Id = utils.RandomId()
|
|
|
|
log.Println(req.Method, req.URL.Path, req.RemoteAddr, context.Id)
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func LogExecutionTimeContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
end := time.Now()
|
|
|
|
log.Println(context.Id, "took", end.Sub(context.Start))
|
|
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func HealthCheckContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
resp.WriteHeader(200)
|
|
resp.Write([]byte("healthy"))
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func FailurePassingContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(_success Continuation, failure Continuation) ContinuationChain {
|
|
return failure(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func IdContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
|
|
return func(success Continuation, _failure Continuation) ContinuationChain {
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func CacheControlMiddleware(next http.Handler, maxAge int) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
header := fmt.Sprintf("public, max-age=%d", maxAge)
|
|
w.Header().Set("Cache-Control", header)
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server {
|
|
mux := http.NewServeMux()
|
|
|
|
fileServer := http.FileServer(http.Dir(argv.StaticPath))
|
|
mux.Handle("GET /static/", http.StripPrefix("/static/", CacheControlMiddleware(fileServer, 3600)))
|
|
|
|
makeRequestContext := func() *RequestContext {
|
|
return &RequestContext{
|
|
DBConn: dbConn,
|
|
Args: argv,
|
|
|
|
TemplateData: &map[string]interface{}{},
|
|
}
|
|
}
|
|
|
|
mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation("home.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /api/health", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(HealthCheckContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /login", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(StartSessionContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /auth", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(InterceptCodeContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /me", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(RefreshSessionContinuation, GoLoginContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /logout", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(LogoutContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /dns", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(ListDNSRecordsContinuation, GoLoginContinuation)(TemplateContinuation("dns.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("POST /dns", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(ListDNSRecordsContinuation, GoLoginContinuation)(CreateDNSRecordContinuation, FailurePassingContinuation)(TemplateContinuation("dns.html", true), TemplateContinuation("dns.html", true))(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("POST /dns/delete", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(DeleteDNSRecordContinuation, GoLoginContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /keys", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(ListAPIKeysContinuation, GoLoginContinuation)(TemplateContinuation("api_keys.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("POST /keys", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(CreateAPIKeyContinuation, GoLoginContinuation)(ListAPIKeysContinuation, ListAPIKeysContinuation)(TemplateContinuation("api_keys.html", true), TemplateContinuation("api_keys.html", true))(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("POST /keys/delete", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(DeleteAPIKeyContinuation, GoLoginContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /guestbook", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(HcaptchaArgsContinuation, HcaptchaArgsContinuation)(ListGuestbookContinuation, ListGuestbookContinuation)(TemplateContinuation("guestbook.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("POST /guestbook", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(HcaptchaArgsContinuation, HcaptchaArgsContinuation)(SignGuestbookContinuation, FailurePassingContinuation)(ListGuestbookContinuation, ListGuestbookContinuation)(TemplateContinuation("guestbook.html", true), TemplateContinuation("guestbook.html", true))(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
mux.HandleFunc("GET /{name}", func(w http.ResponseWriter, r *http.Request) {
|
|
requestContext := makeRequestContext()
|
|
name := r.PathValue("name")
|
|
LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation(name+".html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
})
|
|
|
|
return &http.Server{
|
|
Addr: ":" + fmt.Sprint(argv.Port),
|
|
Handler: mux,
|
|
}
|
|
}
|