mirror of
https://github.com/aunefyren/wrapperr
synced 2025-01-09 16:28:43 +00:00
1a7c66c4b4
Basic Auth on front end Switched to GIN for http routing Reworked middleware
167 lines
5.4 KiB
Go
167 lines
5.4 KiB
Go
package middlewares
|
|
|
|
import (
|
|
"aunefyren/wrapperr/files"
|
|
"aunefyren/wrapperr/models"
|
|
"aunefyren/wrapperr/modules"
|
|
"encoding/base64"
|
|
"errors"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func AuthMiddleware(admin bool) gin.HandlerFunc {
|
|
return func(context *gin.Context) {
|
|
authorizationHeader := context.GetHeader("Authorization")
|
|
if authorizationHeader == "" {
|
|
context.JSON(401, gin.H{"error": "Request does not contain an access token"})
|
|
context.Abort()
|
|
return
|
|
}
|
|
|
|
config, err := files.GetConfig()
|
|
if err != nil {
|
|
log.Println("Failed to load Wrapperr settings. Error: " + err.Error())
|
|
context.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load Wrapperr settings."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
|
|
adminConfig, err := files.GetAdminConfig()
|
|
if err != nil {
|
|
log.Println("Failed to load Wrapperr admin settings. Error: " + err.Error())
|
|
context.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load Wrapperr admin settings."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
|
|
payload, httpStatus, err := AuthGetPayloadFromAuthorization(authorizationHeader, config, adminConfig)
|
|
if err != nil {
|
|
log.Println("Failed to get payload from Authorization token. Error: " + err.Error())
|
|
context.JSON(httpStatus, gin.H{"error": err.Error()})
|
|
context.Abort()
|
|
return
|
|
}
|
|
|
|
if admin {
|
|
adminState, err := files.GetAdminState()
|
|
if err != nil {
|
|
log.Println("Failed to load admin state. Error: " + err.Error())
|
|
context.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load admin state."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
if !adminState {
|
|
log.Println("Trying to verify admin session, but admin is not configured.")
|
|
context.JSON(http.StatusBadRequest, gin.H{"error": "Trying to verify admin session, but admin is not configured."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
if !payload.Admin {
|
|
context.JSON(http.StatusUnauthorized, gin.H{"error": "Session is not an admin session."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
} else {
|
|
if !config.PlexAuth {
|
|
context.JSON(http.StatusBadRequest, gin.H{"error": "Plex Auth is not enabled in the Wrapperr configuration."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
if payload.Admin {
|
|
context.JSON(http.StatusUnauthorized, gin.H{"error": "Session is an admin session."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
if payload.AuthToken == "" {
|
|
context.JSON(http.StatusUnauthorized, gin.H{"error": "Session does not have a Plex Auth Token."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
}
|
|
|
|
context.Next()
|
|
}
|
|
}
|
|
|
|
func AuthGetPayloadFromAuthorization(authorizationHeader string, config models.WrapperrConfig, adminConfig models.AdminConfig) (payload models.Payload, httpStatus int, err error) {
|
|
httpStatus = 200
|
|
err = nil
|
|
payload = models.Payload{}
|
|
|
|
if strings.HasPrefix(strings.ToLower(authorizationHeader), "bearer") {
|
|
token, found := strings.CutPrefix(authorizationHeader, "Bearer ")
|
|
if !found {
|
|
return payload, http.StatusBadRequest, errors.New("'Bearer' part of header not found.")
|
|
}
|
|
|
|
payloadTwo, err := modules.ParseToken(token, config.PrivateKey)
|
|
if err != nil {
|
|
log.Println("Session token not accepted. Error: " + err.Error())
|
|
return payload, http.StatusUnauthorized, errors.New("Session token not accepted. Please relog.")
|
|
}
|
|
|
|
payload = *payloadTwo
|
|
} else if strings.HasPrefix(strings.ToLower(authorizationHeader), "basic") {
|
|
token, found := strings.CutPrefix(authorizationHeader, "Basic ")
|
|
if !found {
|
|
return payload, http.StatusBadRequest, errors.New("'Basic' part of header not found.")
|
|
}
|
|
|
|
rawDecodedtoken, err := base64.StdEncoding.DecodeString(token)
|
|
if err != nil {
|
|
return payload, http.StatusInternalServerError, errors.New("Failed to decode Base64.")
|
|
}
|
|
|
|
authParts := strings.Split(string(rawDecodedtoken), ":")
|
|
if len(authParts) < 2 {
|
|
log.Println("Failed to parse basic auth header. Error: " + err.Error())
|
|
return payload, http.StatusBadRequest, errors.New("Failed to parse basic auth header.")
|
|
}
|
|
|
|
err = modules.ValidateBasicAuth(authParts[0], authParts[1])
|
|
if err != nil {
|
|
log.Println("Failed to validate basic auth header. Error: " + err.Error())
|
|
return payload, http.StatusUnauthorized, errors.New("Failed to validate basic auth header.")
|
|
}
|
|
|
|
_, payloadTwo, err := modules.CreateTokenTwo(config.PrivateKey, adminConfig.AdminUsername, true, "", time.Now())
|
|
if err != nil {
|
|
log.Println("Failed to create token. Error: " + err.Error())
|
|
return payload, http.StatusInternalServerError, errors.New("Failed to create token.")
|
|
}
|
|
|
|
payload = payloadTwo
|
|
}
|
|
return
|
|
}
|
|
|
|
func GetUserIDFromAuthorizationHeader(authorizationHeader string) (userID uuid.UUID, err error) {
|
|
err = nil
|
|
userID = uuid.UUID{}
|
|
|
|
config, err := files.GetConfig()
|
|
if err != nil {
|
|
log.Println("Failed to load Wrapperr settings. Error: " + err.Error())
|
|
return userID, errors.New("Failed to load Wrapperr settings.")
|
|
}
|
|
|
|
adminConfig, err := files.GetAdminConfig()
|
|
if err != nil {
|
|
log.Println("Failed to load Wrapperr admin settings. Error: " + err.Error())
|
|
return userID, errors.New("Failed to load Wrapperr admin settings.")
|
|
}
|
|
|
|
payload, _, err := AuthGetPayloadFromAuthorization(authorizationHeader, config, adminConfig)
|
|
if err != nil {
|
|
log.Println("Failed to get payload from Authorization token. Error: " + err.Error())
|
|
return userID, errors.New("Failed to get payload from Authorization token.")
|
|
}
|
|
|
|
return payload.ID, err
|
|
}
|