parsec/web_api.go
2023-06-02 15:41:51 +08:00

352 lines
9.4 KiB
Go

package main
import (
"encoding/json"
"io/ioutil"
"net/http"
)
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
AuthType string `json:"auth_type"`
HostPeerId string `json:"host_peer_id"`
}
type LoginResponse struct {
UserId int `json:"user_id"`
SessionId string `json:"session_id"`
HostPeerId string `json:"host_peer_id"`
InstanceId string `json:"instance_id"`
}
type ErrorResponse struct {
Error string `json:"error"`
}
type ParsecCommonResponse struct {
Data interface{} `json:"data"`
}
type MeData struct {
Id int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Warp bool `json:"warp"`
Staff bool `json:"staff"`
TeamId string `json:"team_id"`
IsConfirmed bool `json:"is_confirmed"`
TeamIsActive bool `json:"team_is_active"`
IsSaml bool `json:"is_saml"`
IsGatewayEnabled bool `json:"is_gateway_enabled"`
IsRelayEnabled bool `json:"is_relay_enabled"`
HasTfa bool `json:"has_tfa"`
TeamEnforceTfa bool `json:"team_enforce_tfa"`
CanUpgradeSession bool `json:"can_upgrade_session"`
CanDowngradeSession bool `json:"can_downgrade_session"`
AppConfig AppConfig `json:"app_config"`
CohortChannel string `json:"cohort_channel"`
MarketingOptIn bool `json:"marketing_opt_in"`
}
type AppConfig struct {
}
type FriendResponse struct {
Data []FriendData `json:"data"`
HasMore bool `json:"has_more"`
}
type FriendData struct {
}
type HostData struct {
User UserData `json:"user"`
PeerId string `json:"peer_id"`
GameId string `json:"game_id"`
Build string `json:"build"`
Description string `json:"description"`
MaxPlayers int `json:"max_players"`
Mode string `json:"mode"`
Name string `json:"name"`
EventName string `json:"event_name"`
Players int `json:"players"`
Public bool `json:"public"`
GuestAccess bool `json:"guest_access"`
Online bool `json:"online"`
Self bool `json:"self"`
}
type UserData struct {
Id int `json:"id"`
Name string `json:"name"`
Warp bool `json:"warp"`
ExternalId string `json:"external_id"`
ExternalProvider string `json:"external_provider"`
TeamId string `json:"team_id"`
}
type HostResponse struct {
Data []HostData `json:"data"`
HasMore bool `json:"has_more"`
}
func authHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
data, _ := ioutil.ReadAll(r.Body)
defer r.Body.Close()
var login *LoginRequest
json.Unmarshal(data, &login)
Logger.Println("Auth:" + string(data) + "\n")
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if login == nil {
Logger.Println("Error:Auth Failed:" + string(data) + "\n")
w.WriteHeader(403)
w.Write([]byte("{\n\t\"error\": \"Your email/password combination is incorrect.\"\n}"))
return
}
loginUser := parsecService.Login(login.Email, login.Password)
if loginUser == nil {
Logger.Println("Error:Auth Password Error:" + string(data) + "\n")
w.WriteHeader(403)
w.Write([]byte("{\n\t\"error\": \"Your email/password combination is incorrect.\"\n}"))
return
}
var newPeer *PeerInfo
if login.HostPeerId != "" {
peer := parsecService.GetPeer(login.HostPeerId)
if peer != nil && peer.Owner == loginUser.Email {
newPeer = peer
}
}
if newPeer == nil {
newPeer = parsecService.AddPeer(loginUser.Email)
}
session := parsecService.NewSession(loginUser.Email, loginUser.UserId, newPeer.PeerId)
response := &LoginResponse{
UserId: loginUser.UserId,
SessionId: session.SessionId,
HostPeerId: newPeer.PeerId,
InstanceId: "",
}
w.WriteHeader(201)
w.Write(formatJson(response))
}
func GetAuthorization(w http.ResponseWriter, r *http.Request) string {
auth := r.Header.Get("Authorization")
if len(auth) > 10 {
return auth[7:]
}
return ""
}
func meHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
authorization := GetAuthorization(w, r)
var user *UserInfo
session := parsecService.GetSession(authorization)
if session == nil {
err := &ErrorResponse{
Error: "invalid session ID",
}
w.WriteHeader(401)
w.Write(formatJson(err))
return
}
user = parsecService.GetUserByEmail(session.Email)
if user == nil {
err := &ErrorResponse{
Error: "invalid session ID",
}
w.WriteHeader(401)
w.Write(formatJson(err))
return
}
data := &MeData{
Id: user.UserId,
Name: user.Email,
Email: user.Email,
Warp: true,
Staff: true,
TeamId: "",
TeamIsActive: false,
IsSaml: false,
IsGatewayEnabled: false,
IsRelayEnabled: false,
HasTfa: false,
TeamEnforceTfa: false,
CanUpgradeSession: false,
CanDowngradeSession: false,
IsConfirmed: true,
CohortChannel: "release19",
MarketingOptIn: false,
AppConfig: AppConfig{},
}
response := ParsecCommonResponse{
Data: data,
}
Logger.Println("Me:" + string(formatJson(response)) + "\n")
w.Write(formatJson(response))
}
func friendHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
authorization := GetAuthorization(w, r)
session := parsecService.GetSession(authorization)
if session == nil {
err := &ErrorResponse{
Error: "invalid session ID",
}
w.WriteHeader(401)
w.Write(formatJson(err))
return
}
response := FriendResponse{
Data: make([]FriendData, 0),
HasMore: false,
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Write(formatJson(response))
}
func exitHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
}
func metricsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(204)
}
func eventsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(204)
}
func hostsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Add("access-control-allow-origin", "*")
if r.Method == "OPTIONS" {
w.Header().Add("access-control-allow-methods", "*")
w.Header().Add("access-control-allow-headers", "*")
w.Header().Add("access-control-max-age", "300")
w.WriteHeader(200)
return
}
authorization := GetAuthorization(w, r)
var user *UserInfo
session := parsecService.GetSession(authorization)
if session == nil {
err := &ErrorResponse{
Error: "invalid session ID",
}
w.WriteHeader(401)
w.Write(formatJson(err))
return
}
user = parsecService.GetUserByEmail(session.Email)
if user == nil {
err := &ErrorResponse{
Error: "invalid session ID",
}
w.WriteHeader(401)
w.Write(formatJson(err))
return
}
var hosts []HostData
if user != nil {
peers := parsecService.GetPeersByEmail(user.Email)
for _, peer := range peers {
if !peer.Online {
continue
}
host := &HostData{
User: UserData{
Id: user.UserId,
Name: user.Email,
Warp: true,
ExternalId: "",
ExternalProvider: "",
TeamId: "",
},
PeerId: peer.PeerId,
GameId: "",
Build: peer.Build,
Description: "",
MaxPlayers: 20,
Mode: "desktop",
Name: peer.Name,
Players: peer.Players,
Public: peer.Public,
Self: session.HostPeerId == peer.PeerId,
}
hosts = append(hosts, *host)
}
response := &HostResponse{
Data: hosts,
HasMore: false,
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Write(formatJson(response))
}
}