refactor(auth): move authentication params to headers and simplify validation
- Move token and timestamp validation to HTTP headers - Simplify ValidateTimeStamp to return boolean - Update AddUser to use default "visitor" type - Remove redundant timestamp and token fields from request structs - Update API documentation to reflect header-based authentication
This commit is contained in:
+23
-62
@@ -11,16 +11,13 @@ import (
|
||||
)
|
||||
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username"`
|
||||
Passwd string `json:"passwd"`
|
||||
TimeStamp int64 `json:"timeStamp"`
|
||||
Type string `json:"type"`
|
||||
Username string `json:"username"`
|
||||
Passwd string `json:"passwd"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Passwd string `json:"passwd"`
|
||||
TimeStamp int64 `json:"timeStamp"`
|
||||
Username string `json:"username"`
|
||||
Passwd string `json:"passwd"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
@@ -36,6 +33,11 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !ValidateTimeStamp(r.Header) {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
@@ -57,11 +59,6 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := ValidateTimeStamp(req.TimeStamp); err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if !isValidInput(req.Username) || !isValidInput(req.Passwd) {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
|
||||
postLog.Debug(fmt.Sprintf("[RegisterHandler] New user registration failed: username or password contains illegal characters \"%s\":\"%s\"", req.Username, req.Passwd))
|
||||
@@ -74,23 +71,7 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
userType := req.Type
|
||||
if userType == "" {
|
||||
userType = "visitor"
|
||||
}
|
||||
|
||||
validTypes := map[string]bool{
|
||||
"superuser": true,
|
||||
"admin": true,
|
||||
"visitor": true,
|
||||
}
|
||||
if !validTypes[userType] {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid user type")
|
||||
postLog.Warning(fmt.Sprintf("[RegisterHandler] New user registration failed: invalid user type \"%s\"", userType))
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := AddUser(req.Username, req.Passwd, userType)
|
||||
userID, err := AddUser(req.Username, req.Passwd)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
postLog.Error(fmt.Sprintf("[RegisterHandler] Failed to register user \"%s\": %v", req.Username, err))
|
||||
@@ -118,6 +99,11 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !ValidateTimeStamp(r.Header) {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
@@ -139,12 +125,6 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := ValidateTimeStamp(req.TimeStamp); err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
postLog.Warning(fmt.Sprintf("[LoginHandler] User \"%s\" Login failed: invalid timestamp \"%d\"", req.Username, req.TimeStamp))
|
||||
return
|
||||
}
|
||||
|
||||
if !isValidInput(req.Username) || !isValidInput(req.Passwd) {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
|
||||
postLog.Debug(fmt.Sprintf("[LoginHandler] Login failed: username or password contains illegal characters \"%s\":\"%s\"", req.Username, req.Passwd))
|
||||
@@ -218,7 +198,7 @@ func SendSuccessResponse(w http.ResponseWriter, message string, data interface{}
|
||||
w.Write(jsonResp)
|
||||
}
|
||||
|
||||
func ValidateRequest(w http.ResponseWriter, r *http.Request, requiredFields ...string) (int, string, error) {
|
||||
func ValidateRequest(w http.ResponseWriter, r *http.Request, requiredFields ...string) (int, string, error) { // ValidateRequest validates the request body and header
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("Failed to read request body: %w", err)
|
||||
@@ -234,20 +214,13 @@ func ValidateRequestWithBody(w http.ResponseWriter, r *http.Request, body []byte
|
||||
return 0, "", fmt.Errorf("Invalid request format: %w", err)
|
||||
}
|
||||
|
||||
token, ok := reqMap["token"].(string)
|
||||
if !ok || token == "" {
|
||||
return 0, "", fmt.Errorf("Token is required: %s", token)
|
||||
token := r.Header.Get("X-Token")
|
||||
if token == "" {
|
||||
return 0, "", fmt.Errorf("Token is required in header: %s", token)
|
||||
}
|
||||
|
||||
timeStamp := int64(0)
|
||||
if ts, ok := reqMap["timeStamp"].(float64); ok {
|
||||
timeStamp = int64(ts)
|
||||
} else if !globalConfig.Debug {
|
||||
return 0, "", fmt.Errorf("Timestamp is required: %d", timeStamp)
|
||||
}
|
||||
|
||||
if err := ValidateTimeStamp(timeStamp); err != nil {
|
||||
return 0, "", fmt.Errorf("Invalid timestamp: %w", err)
|
||||
if !ValidateTimeStamp(r.Header) {
|
||||
return 0, "", fmt.Errorf("Invalid or missing X-Timestamp in header")
|
||||
}
|
||||
|
||||
userID, err := extractUserIDFromToken(token)
|
||||
@@ -274,20 +247,8 @@ func ValidateRequestWithHeader(w http.ResponseWriter, r *http.Request, requiredF
|
||||
return 0, "", fmt.Errorf("Token is required in header: %s", token)
|
||||
}
|
||||
|
||||
timeStampStr := r.Header.Get("X-Timestamp")
|
||||
timeStamp := int64(0)
|
||||
if timeStampStr != "" {
|
||||
var err error
|
||||
timeStamp, err = strconv.ParseInt(timeStampStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("Invalid timestamp format in header: %w", err)
|
||||
}
|
||||
} else if !globalConfig.Debug {
|
||||
return 0, "", fmt.Errorf("Timestamp is required in header: %s", timeStampStr)
|
||||
}
|
||||
|
||||
if err := ValidateTimeStamp(timeStamp); err != nil {
|
||||
return 0, "", err
|
||||
if !ValidateTimeStamp(r.Header) {
|
||||
return 0, "", fmt.Errorf("Invalid or missing X-Timestamp in header")
|
||||
}
|
||||
|
||||
userID, err := extractUserIDFromToken(token)
|
||||
|
||||
Reference in New Issue
Block a user