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)) } }