forked from TripwireTeam/tripwire
215 lines
4.4 KiB
Go
215 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"image"
|
|
_ "image/png"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
func logInEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
var details UserCredentials
|
|
err := unmarshalTo(r, &details)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
invalidCreds := YggError{
|
|
Code: 401,
|
|
Error: "Unauthorized",
|
|
ErrorMessage: "Invalid credentials.",
|
|
}
|
|
exists, err := playerExistsByUsername(details.Username)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
if !exists {
|
|
sendError(w, invalidCreds)
|
|
return
|
|
}
|
|
|
|
correct, err := checkPlayerPassByUsername(details.Username, details.Password)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
if correct {
|
|
response := WebLogInResponse{}
|
|
webToken, err := getWebToken(details.Username, details.Password)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
player, err := getPlayerByUsername(details.Username)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
response.Token = webToken
|
|
response.UUID = player.UUID
|
|
response.Username = player.Username
|
|
|
|
sendJSON(w, response)
|
|
} else {
|
|
sendError(w, YggError{
|
|
Code: 401,
|
|
Error: "Unauthorized",
|
|
ErrorMessage: "Invalid credentials.",
|
|
})
|
|
}
|
|
}
|
|
|
|
func getTextureEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
uuid := mux.Vars(r)["uuid"]
|
|
query := r.URL.Query()
|
|
if !query.Has("type") {
|
|
sendError(w, YggError{
|
|
Code: 400,
|
|
Error: "Bad Request",
|
|
ErrorMessage: "Must specify texture type. Add ?type=skin or ?type=cape to the URL.",
|
|
})
|
|
return
|
|
}
|
|
textureId := query.Get("type")
|
|
if !(textureId == "skin" || textureId == "cape") {
|
|
sendError(w, YggError{
|
|
Code: 400,
|
|
Error: "Bad Request",
|
|
ErrorMessage: "Invalid texture type.",
|
|
})
|
|
return
|
|
}
|
|
|
|
skin, err := getPlayerTexture(textureId, uuid)
|
|
if err != nil {
|
|
if !errors.Is(err, &NotFoundError{}) {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
skin, err = os.ReadFile("default.png")
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
}
|
|
w.Header().Set("Content-Type", "image/png")
|
|
w.Write(skin)
|
|
}
|
|
|
|
func setTextureEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
uuid := mux.Vars(r)["uuid"]
|
|
query := r.URL.Query()
|
|
if !query.Has("type") {
|
|
sendError(w, YggError{Code: 400, Error: "Bad Request", ErrorMessage: "Must specify texture type. Add ?type=skin or ?type=cape to the URL."})
|
|
return
|
|
}
|
|
textureId := query.Get("type")
|
|
if !(textureId == "skin" || textureId == "cape") {
|
|
sendError(w, YggError{
|
|
Code: 400,
|
|
Error: "Bad Request",
|
|
ErrorMessage: "Invalid texture type.",
|
|
})
|
|
return
|
|
}
|
|
|
|
if len(uuid) == 32 {
|
|
uuid = growUUID(uuid)
|
|
}
|
|
|
|
if len(uuid) != 36 {
|
|
sendError(w, YggError{
|
|
Code: 400,
|
|
Error: "Bad Request",
|
|
ErrorMessage: "Invalid UUID.",
|
|
})
|
|
return
|
|
}
|
|
|
|
r.ParseMultipartForm(int64(config.MaxTextureSize))
|
|
|
|
token := r.FormValue("token")
|
|
|
|
player, err := getPlayerByUUID(uuid)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
if token != player.WebToken {
|
|
sendError(w, YggError{Code: 400, Error: "Bad Request", ErrorMessage: "Invalid credentials."})
|
|
return
|
|
}
|
|
|
|
file, _, err := recievePNG("file", w, r)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
reader := bytes.NewReader(file)
|
|
img, _, err := image.Decode(reader)
|
|
if err != nil {
|
|
sendError(w, YggError{
|
|
Code: 400,
|
|
Error: "Bad Request",
|
|
ErrorMessage: "The request data is malformed.",
|
|
})
|
|
return
|
|
}
|
|
|
|
bounds := img.Bounds()
|
|
targetX := 64
|
|
targetY := 64
|
|
if textureId == "cape" {
|
|
targetY = 32
|
|
}
|
|
|
|
if bounds.Dx() != targetX || bounds.Dy() != targetY {
|
|
sendError(w, YggError{
|
|
Code: 400,
|
|
Error: "Bad Request",
|
|
ErrorMessage: "The request data is malformed.",
|
|
})
|
|
return
|
|
}
|
|
|
|
err = setPlayerTexture(textureId, uuid, file)
|
|
if err != nil {
|
|
handleError(w, err)
|
|
return
|
|
}
|
|
|
|
sendEmpty(w)
|
|
}
|
|
|
|
func rootRedirect(w http.ResponseWriter, r *http.Request) {
|
|
if strings.HasPrefix(r.Header.Get("User-Agent"), "Java") {
|
|
rootEndpoint(w, r)
|
|
return
|
|
}
|
|
http.Redirect(w, r, "/web", http.StatusMovedPermanently)
|
|
}
|
|
|
|
func registerWebEndpoints(r *mux.Router) {
|
|
webDir := "/web"
|
|
r.HandleFunc("/", rootRedirect)
|
|
r.HandleFunc("/webapi/logIn", logInEndpoint).Methods("POST")
|
|
r.PathPrefix(webDir).
|
|
Handler(http.StripPrefix(webDir, http.FileServer(http.Dir("."+webDir))))
|
|
|
|
r.HandleFunc("/getTexture/{uuid}", getTextureEndpoint).Methods("GET")
|
|
r.HandleFunc("/setTexture/{uuid}", setTextureEndpoint).Methods("POST")
|
|
}
|