summary refs log tree commit diff
path: root/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'handlers')
-rw-r--r--handlers/handler.go56
-rw-r--r--handlers/portgate.go45
2 files changed, 79 insertions, 22 deletions
diff --git a/handlers/handler.go b/handlers/handler.go
index 6484c61..56801a3 100644
--- a/handlers/handler.go
+++ b/handlers/handler.go
@@ -5,6 +5,7 @@ import (
 	"github.com/valyala/fasthttp"
 	"net/http"
 	"portgate"
+	"strings"
 )
 
 // RequestHandler keeps data relevant to the request handlers.
@@ -13,12 +14,29 @@ type RequestHandler struct {
 	config *portgate.Config
 	// HTTP Client for requesting resources from the destination host.
 	client fasthttp.Client
+	// Handler for static Portgate assets.
+	staticHandler fasthttp.RequestHandler
+	// Templates for Portgate pages.
+	templates portgate.Templates
 }
 
-func NewRequestHandler(config *portgate.Config) RequestHandler {
+// NewRequestHandler creates a new RequestHandler instance.
+func NewRequestHandler(config *portgate.Config, templates portgate.Templates) RequestHandler {
+	// Serves static Portgate files when called.
+	fs := fasthttp.FS{
+		Root: "./assets/static/",
+		PathRewrite: func(ctx *fasthttp.RequestCtx) []byte {
+			return []byte(strings.TrimPrefix(string(ctx.Path()), "/_portgate/static"))
+		},
+		PathNotFound: nil,
+	}
+	staticHandler := fs.NewRequestHandler()
+
 	return RequestHandler{
-		config: config,
-		client: fasthttp.Client{},
+		config:        config,
+		client:        fasthttp.Client{},
+		staticHandler: staticHandler,
+		templates:     templates,
 	}
 }
 
@@ -26,24 +44,26 @@ func NewRequestHandler(config *portgate.Config) RequestHandler {
 func (h *RequestHandler) HandleRequest(ctx *fasthttp.RequestCtx) {
 	path := portgate.ParsePath(string(ctx.Path()))
 
+	if path.IsPortgatePath() {
+		h.handlePortgateRequest(ctx, path)
+		return
+	}
+
 	if path.DestinationIdentifier == -1 {
-		// We were not given a port.
+		// We were not given a destination.
 
-		if path.ResourcePath == "/_portgate" {
-			h.handlePortgateRequest(ctx)
+		// Try to grab actual destination from Referer header.
+		// This can help us if the user followed an absolute link on a proxied page.
+		refererPath, err := portgate.ParsePathFromReferer(path, string(ctx.Request.Header.Referer()))
+		if err != nil || refererPath.DestinationIdentifier == -1 {
+			// The referer path also has no destination
+			h.handleUnknownRequest(ctx)
 		} else {
-			// Try to grab actual destination from Referer header.
-			refererPath, err := portgate.ParsePathFromReferer(path, string(ctx.Request.Header.Referer()))
-			if err != nil || refererPath.DestinationIdentifier == -1 {
-				// The referer path also has no destination
-				h.handleUnknownRequest(ctx)
-			} else {
-				// We found the destination from the referer path, so we
-				// redirect the user to the Portgate URL they should've requested.
-
-				portgateUrl := fmt.Sprintf("/%d%s", refererPath.DestinationIdentifier, refererPath.ResourcePath)
-				ctx.Redirect(portgateUrl, http.StatusTemporaryRedirect)
-			}
+			// We found the destination from the referer path, so we
+			// redirect the user to the Portgate URL they should've requested.
+
+			portgateUrl := fmt.Sprintf("/%d%s", refererPath.DestinationIdentifier, refererPath.ResourcePath)
+			ctx.Redirect(portgateUrl, http.StatusTemporaryRedirect)
 		}
 	} else {
 		// We were given a port, so we have to pass the request through to the destination host.
diff --git a/handlers/portgate.go b/handlers/portgate.go
index 9d4f3ef..1cd9bb8 100644
--- a/handlers/portgate.go
+++ b/handlers/portgate.go
@@ -1,10 +1,47 @@
 package handlers
 
-import "github.com/valyala/fasthttp"
+import (
+	"github.com/valyala/fasthttp"
+	"net/http"
+	"portgate"
+)
 
 // handlePortgateRequest handles all Portgate specific request for either showing Portgate
 // specific pages or handling creation of authorization tokens.
-func (h *RequestHandler) handlePortgateRequest(ctx *fasthttp.RequestCtx) {
-	// TODO: Implement authentication, authorization
-	_, _ = ctx.WriteString("Portgate request.")
+func (h *RequestHandler) handlePortgateRequest(ctx *fasthttp.RequestCtx, path portgate.Path) {
+	if path.IsPortgateStaticPath() {
+		h.staticHandler(ctx)
+	} else {
+		// TODO: Implement authentication, authorization
+		h.handlePortgateIndexRequest(ctx)
+	}
+}
+
+// handlePortgateIndexRequest delegates requests directed at /_portgate.
+func (h *RequestHandler) handlePortgateIndexRequest(ctx *fasthttp.RequestCtx) {
+	switch string(ctx.Method()) {
+	case "GET":
+		// If we received a GET request, the user wants to see either the login page,
+		// or an info page if they're already authenticated.
+		h.handlePortgatePageRequest(ctx)
+	case "POST":
+		// If we received a POST request, the user wants to get authorization to Portgate.
+		h.handleAuthenticateRequest(ctx)
+	}
+}
+
+// handlePortgatePageRequest renders the Portgate page with either the authentication page or
+// a basic information page.
+func (h *RequestHandler) handlePortgatePageRequest(ctx *fasthttp.RequestCtx) {
+	// We render the page template and pass it to the user.
+	ctx.Response.Header.SetContentType("text/html")
+	err := h.templates.ExecuteTemplate(ctx, "authenticate.template.html", nil)
+	if err != nil {
+		ctx.SetStatusCode(http.StatusInternalServerError)
+		_, _ = ctx.WriteString("An error occurred.")
+	}
+}
+
+func (h *RequestHandler) handleAuthenticateRequest(ctx *fasthttp.RequestCtx) {
+	// TODO
 }