Skip to content

Commit

Permalink
saving and abandoning in favour of ssr approach
Browse files Browse the repository at this point in the history
  • Loading branch information
mfreeman451 committed Feb 26, 2025
1 parent 0291fcc commit a83b199
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
64 changes: 60 additions & 4 deletions pkg/cloud/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
package api

import (
"crypto/rand"
"embed"
"encoding/base64"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -174,14 +176,27 @@ func (*APIServer) writeError(w http.ResponseWriter, msg string, status int) {
log.Printf("%s: %d", msg, status)
}

// generateCSRFToken creates a random token.
func generateCSRFToken() (string, error) {
b := make([]byte, 32)

Check failure on line 181 in pkg/cloud/api/server.go

View workflow job for this annotation

GitHub Actions / lint

Magic number: 32, in <argument> detected (mnd)
_, err := rand.Read(b)
if err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(b), nil

Check failure on line 186 in pkg/cloud/api/server.go

View workflow job for this annotation

GitHub Actions / lint

return statements should not be cuddled if block has more than two lines (wsl)
}

func (s *APIServer) setupRoutes() {
log.Println("Setting up routes...")

// 1. Proxy routes first, no middleware
// Apply CSRF middleware to all routes
s.router.Use(s.csrfMiddleware)

// Proxy routes
s.setupWebProxyRoutes("localhost:8090")
log.Println("Web proxy routes registered for /web-api/")

// 2. API routes with middleware on a subrouter
// API routes with additional middleware
apiRouter := s.router.PathPrefix("/api").Subrouter()
middlewareChain := func(next http.Handler) http.Handler {
return srHttp.CommonMiddleware(srHttp.APIKeyMiddleware(next))
Expand All @@ -197,7 +212,7 @@ func (s *APIServer) setupRoutes() {
apiRouter.HandleFunc("/nodes/{id}/snmp", s.getSNMPData).Methods("GET")
log.Println("API routes registered with middleware under /api/")

// 3. Static file serving as fallback
// Static file serving
s.configureStaticServing()
log.Println("Static file serving registered")
}
Expand All @@ -209,10 +224,51 @@ func (s *APIServer) setupWebProxyRoutes(listenAddr string) {
log.Printf("Proxy handler hit for %s", r.URL.Path)
s.proxyAPIRequest(w, r, listenAddr)
}
webProxyRouter.PathPrefix("/").HandlerFunc(proxyHandler) // Match all under /web-api/
webProxyRouter.PathPrefix("/").HandlerFunc(proxyHandler)
s.router.PathPrefix("/web-api/").Handler(webProxyRouter)
}

// csrfMiddleware ensures CSRF token is set and validated

Check failure on line 231 in pkg/cloud/api/server.go

View workflow job for this annotation

GitHub Actions / lint

Comment should end in a period (godot)
func (s *APIServer) csrfMiddleware(next http.Handler) http.Handler {

Check failure on line 232 in pkg/cloud/api/server.go

View workflow job for this annotation

GitHub Actions / lint

cyclomatic complexity 11 of func `(*APIServer).csrfMiddleware` is high (> 10) (gocyclo)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Set CSRF token on any GET request not under /web-api/ or /api/
if r.Method == http.MethodGet && !strings.HasPrefix(r.URL.Path, "/web-api/") && !strings.HasPrefix(r.URL.Path, "/api/") {
token, err := generateCSRFToken()
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
http.SetCookie(w, &http.Cookie{
Name: "csrf_token",
Value: token,
Path: "/",
HttpOnly: false,
SameSite: http.SameSiteLaxMode,
})
log.Printf("Set CSRF token: %s for %s", token, r.URL.Path)
}

// Validate CSRF token for /web-api/ requests
if strings.HasPrefix(r.URL.Path, "/web-api/") {
cookie, err := r.Cookie("csrf_token")
if err != nil || cookie == nil || cookie.Value == "" {
http.Error(w, "CSRF token missing", http.StatusForbidden)
log.Printf("CSRF token missing for %s", r.URL.Path)
return
}
headerToken := r.Header.Get("X-CSRF-Token")
if headerToken == "" || headerToken != cookie.Value {

Check failure on line 260 in pkg/cloud/api/server.go

View workflow job for this annotation

GitHub Actions / lint

only one cuddle assignment allowed before if statement (wsl)
http.Error(w, "Invalid CSRF token", http.StatusForbidden)
log.Printf("Invalid CSRF token for %s", r.URL.Path)
return
}
log.Printf("CSRF token validated for %s", r.URL.Path)

Check failure on line 265 in pkg/cloud/api/server.go

View workflow job for this annotation

GitHub Actions / lint

expressions should not be cuddled with blocks (wsl)
}

next.ServeHTTP(w, r)
})
}

// proxyAPIRequest forwards an incoming request to an internal API server.
func (s *APIServer) proxyAPIRequest(w http.ResponseWriter, r *http.Request, serverAddr string) {
apiPath := strings.TrimPrefix(r.URL.Path, "/web-api/")
Expand Down
2 changes: 1 addition & 1 deletion pkg/cloud/api/web/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<link rel="shortcut icon" href="/favicons/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
<link rel="manifest" href="/favicons/site.webmanifest" />
<script type="module" crossorigin src="/assets/index-fWfe1cpu.js"></script>
<script type="module" crossorigin src="/assets/index-Dm_iFvSy.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BvOLntxh.css">
</head>
<body>
Expand Down
2 changes: 1 addition & 1 deletion web/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<link rel="shortcut icon" href="/favicons/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
<link rel="manifest" href="/favicons/site.webmanifest" />
<script type="module" crossorigin src="/assets/index-fWfe1cpu.js"></script>
<script type="module" crossorigin src="/assets/index-Dm_iFvSy.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BvOLntxh.css">
</head>
<body>
Expand Down
18 changes: 16 additions & 2 deletions web/src/services/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,23 @@
*/

export const apiRequest = async (url, options = {}) => {
console.log('API request to (originalUrl): ', url);
const headers = { ...options.headers || {} };
const proxyUrl = url.startsWith('/api/') ? `/web-api${url}` : url; // Makes /api/status -> /web-api/api/status
const proxyUrl = url.startsWith('/api/') ? `/web-api${url}` : url;

// Fetch CSRF token from cookie
const getCookie = (name) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
};
const csrfToken = getCookie('csrf_token');
if (csrfToken) {
headers['X-CSRF-Token'] = csrfToken;
console.log(`Sending CSRF token: ${csrfToken}`);
} else {
console.warn('CSRF token not found in cookies');
}

console.log(`API request to: ${proxyUrl}`);
return fetch(proxyUrl, { ...options, headers });
};
Expand Down

0 comments on commit a83b199

Please sign in to comment.