Collect the username when data scouting data is submitted
This patch adds the username of the person that is submitting scouting
data.
I kind of amended the existing unit test to validate this feature by
injecting a fake username at the right places. It doesn't validate
actual HTTPS traffic, but it's good enough for now.
Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I483cf30fd046965b23916b129a074906b586b096
diff --git a/scouting/webserver/requests/requests.go b/scouting/webserver/requests/requests.go
index 245891a..2076030 100644
--- a/scouting/webserver/requests/requests.go
+++ b/scouting/webserver/requests/requests.go
@@ -1,9 +1,11 @@
package requests
import (
+ "encoding/base64"
"errors"
"fmt"
"io"
+ "log"
"net/http"
"strconv"
"strings"
@@ -80,12 +82,44 @@
return result, success
}
+// Parses the authorization information that the browser inserts into the
+// headers. The authorization follows this format:
+//
+// req.Headers["Authorization"] = []string{"Basic <base64 encoded username:password>"}
+func parseUsername(req *http.Request) string {
+ auth, ok := req.Header["Authorization"]
+ if !ok {
+ return "unknown"
+ }
+
+ parts := strings.Split(auth[0], " ")
+ if !(len(parts) == 2 && parts[0] == "Basic") {
+ return "unknown"
+ }
+
+ info, err := base64.StdEncoding.DecodeString(parts[1])
+ if err != nil {
+ log.Println("ERROR: Failed to parse Basic authentication.")
+ return "unknown"
+ }
+
+ loginParts := strings.Split(string(info), ":")
+ if len(loginParts) != 2 {
+ return "unknown"
+ }
+ return loginParts[0]
+}
+
// Handles a SubmitDataScouting request.
type submitDataScoutingHandler struct {
db Database
}
func (handler submitDataScoutingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ // Get the username of the person submitting the data.
+ username := parseUsername(req)
+ log.Println("Got data scouting data from", username)
+
requestBytes, err := io.ReadAll(req.Body)
if err != nil {
respondWithError(w, http.StatusBadRequest, fmt.Sprint("Failed to read request bytes:", err))
@@ -108,6 +142,7 @@
LowerGoalShots: request.LowerGoalTele(),
PlayedDefense: request.DefenseRating(),
Climbing: request.Climbing(),
+ CollectedBy: username,
}
err = handler.db.AddToStats(stats)
@@ -152,7 +187,7 @@
matches, err := handler.db.ReturnMatches()
if err != nil {
- respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Faled to query database: ", err))
+ respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to query database: ", err))
return
}
@@ -281,6 +316,7 @@
LowerGoalTele: stat.LowerGoalShots,
DefenseRating: stat.PlayedDefense,
Climbing: stat.Climbing,
+ CollectedBy: stat.CollectedBy,
})
}