aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpg9182 <96569817+pg9182@users.noreply.github.com>2023-02-27 00:38:33 -0500
committerpg9182 <96569817+pg9182@users.noreply.github.com>2023-03-04 00:49:32 -0500
commitd704eaddcb833b14b5e18756925a47081b429163 (patch)
treecc3ec7c14276ff9399807c66d43d92e9b203c758
parentabd04681463b364edc92a91bce006fb6ff1f5a37 (diff)
downloadAtlas-d704eaddcb833b14b5e18756925a47081b429163.tar.gz
Atlas-d704eaddcb833b14b5e18756925a47081b429163.zip
pkg/api/api0: Implement EAX username source
-rw-r--r--pkg/api/api0/api.go4
-rw-r--r--pkg/api/api0/client.go94
-rw-r--r--pkg/api/api0/metrics.go12
3 files changed, 110 insertions, 0 deletions
diff --git a/pkg/api/api0/api.go b/pkg/api/api0/api.go
index 3ed5999..afce1d4 100644
--- a/pkg/api/api0/api.go
+++ b/pkg/api/api0/api.go
@@ -26,6 +26,7 @@ import (
"github.com/klauspost/compress/gzip"
"github.com/pg9182/ip2x"
+ "github.com/r2northstar/atlas/pkg/eax"
"github.com/r2northstar/atlas/pkg/metricsx"
"github.com/r2northstar/atlas/pkg/origin"
"github.com/rs/zerolog/hlog"
@@ -50,6 +51,9 @@ type Handler struct {
// usernames.
OriginAuthMgr *origin.AuthMgr
+ // EAXClient makes requests to the EAX API.
+ EAXClient *eax.Client
+
// CleanBadWords is used to filter bad words from server names and
// descriptions. If not provided, words will not be filtered.
CleanBadWords func(s string) string
diff --git a/pkg/api/api0/client.go b/pkg/api/api0/client.go
index 9b1408f..45f006b 100644
--- a/pkg/api/api0/client.go
+++ b/pkg/api/api0/client.go
@@ -12,6 +12,7 @@ import (
"time"
"github.com/r2northstar/atlas/pkg/api/api0/api0gameserver"
+ "github.com/r2northstar/atlas/pkg/eax"
"github.com/r2northstar/atlas/pkg/origin"
"github.com/r2northstar/atlas/pkg/pdata"
"github.com/r2northstar/atlas/pkg/stryder"
@@ -27,6 +28,19 @@ const (
// Get the username from the Origin API.
UsernameSourceOrigin UsernameSource = "origin"
+
+ // Get the username from the Origin API, but fall back to EAX on failure.
+ UsernameSourceOriginEAX UsernameSource = "origin-eax"
+
+ // Get the username from EAX.
+ UsernameSourceEAX UsernameSource = "eax"
+
+ // Get the username from the Origin API, but also check EAX and warn if it's
+ // different.
+ UsernameSourceOriginEAXDebug UsernameSource = "origin-eax-debug"
+
+ // Get the username from EAX, but fall back to the Origin API on failure.
+ UsernameSourceEAXOrigin UsernameSource = "eax-origin"
)
type MainMenuPromos struct {
@@ -276,6 +290,46 @@ func (h *Handler) lookupUsername(r *http.Request, uid uint64) (username string)
break
case UsernameSourceOrigin:
username, _ = h.lookupUsernameOrigin(r, uid)
+ case UsernameSourceOriginEAX:
+ username, _ = h.lookupUsernameOrigin(r, uid)
+ if username == "" {
+ if eaxUsername, ok := h.lookupUsernameEAX(r, uid); ok {
+ username = eaxUsername
+ hlog.FromRequest(r).Warn().
+ Uint64("uid", uid).
+ Str("origin_username", eaxUsername).
+ Msgf("failed to get username from origin, but got it from eax")
+ }
+ }
+ case UsernameSourceOriginEAXDebug:
+ username, _ = h.lookupUsernameOrigin(r, uid)
+ if eaxUsername, ok := h.lookupUsernameEAX(r, uid); ok {
+ if eaxUsername != username {
+ hlog.FromRequest(r).Warn().
+ Uint64("uid", uid).
+ Str("origin_username", username).
+ Str("eax_username", eaxUsername).
+ Msgf("got username from origin and eax, but they don't match; using the origin one")
+ }
+ } else {
+ hlog.FromRequest(r).Warn().
+ Uint64("uid", uid).
+ Str("origin_username", username).
+ Msgf("got username from origin, but failed to get username from eax")
+ }
+ case UsernameSourceEAX:
+ username, _ = h.lookupUsernameEAX(r, uid)
+ case UsernameSourceEAXOrigin:
+ username, _ = h.lookupUsernameEAX(r, uid)
+ if username == "" {
+ if originUsername, ok := h.lookupUsernameOrigin(r, uid); ok {
+ username = originUsername
+ hlog.FromRequest(r).Warn().
+ Uint64("uid", uid).
+ Str("origin_username", originUsername).
+ Msgf("failed to get username from eax, but got it from origin")
+ }
+ }
default:
hlog.FromRequest(r).Error().
Msgf("unknown username source %q", h.UsernameSource)
@@ -345,6 +399,46 @@ func (h *Handler) lookupUsernameOrigin(r *http.Request, uid uint64) (username st
return
}
+// lookupUsernameEAX gets the username for uid from the EAX API, returning an
+// empty string if a username does not exist for the uid, and false on error.
+func (h *Handler) lookupUsernameEAX(r *http.Request, uid uint64) (username string, ok bool) {
+ if h.EAXClient == nil {
+ hlog.FromRequest(r).Error().
+ Str("username_source", "eax").
+ Msgf("no eax client available for username lookup")
+ return
+ }
+ eaxStart := time.Now()
+ if p, err := h.EAXClient.PlayerIDByPD(r.Context(), uid); err == nil {
+ if p != nil {
+ username = p.DisplayName
+ h.m().client_originauth_eax_username_lookup_calls_total.success.Inc()
+ } else {
+ hlog.FromRequest(r).Warn().
+ Err(err).
+ Uint64("uid", uid).
+ Str("username_source", "eax").
+ Msgf("no eax username found for uid")
+ h.m().client_originauth_eax_username_lookup_calls_total.notfound.Inc()
+ }
+ ok = true
+ } else if errors.Is(err, eax.ErrVersionRequired) || errors.Is(err, eax.ErrAutoUpdateBackoff) {
+ hlog.FromRequest(r).Error().
+ Err(err).
+ Str("username_source", "eax").
+ Msgf("eax update check failure")
+ h.m().client_originauth_eax_username_lookup_calls_total.fail_update_check.Inc()
+ } else if !errors.Is(err, context.Canceled) {
+ hlog.FromRequest(r).Error().
+ Err(err).
+ Str("username_source", "eax").
+ Msgf("failed to get eax player info")
+ h.m().client_originauth_eax_username_lookup_calls_total.fail_other_error.Inc()
+ }
+ h.m().client_originauth_eax_username_lookup_duration_seconds.UpdateDuration(eaxStart)
+ return
+}
+
func (h *Handler) handleClientAuthWithServer(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodOptions && r.Method != http.MethodPost {
h.m().client_authwithserver_requests_total.http_method_not_allowed.Inc()
diff --git a/pkg/api/api0/metrics.go b/pkg/api/api0/metrics.go
index 8f9a0b5..46c8615 100644
--- a/pkg/api/api0/metrics.go
+++ b/pkg/api/api0/metrics.go
@@ -79,6 +79,13 @@ type apiMetrics struct {
fail_authtok_refresh *metrics.Counter
fail_other_error *metrics.Counter
}
+ client_originauth_eax_username_lookup_duration_seconds *metrics.Histogram
+ client_originauth_eax_username_lookup_calls_total struct {
+ success *metrics.Counter
+ notfound *metrics.Counter
+ fail_update_check *metrics.Counter
+ fail_other_error *metrics.Counter
+ }
client_authwithserver_requests_total struct {
success *metrics.Counter
reject_bad_request *metrics.Counter
@@ -246,6 +253,11 @@ func (h *Handler) m() *apiMetrics {
mo.client_originauth_origin_username_lookup_calls_total.notfound = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="notfound"}`)
mo.client_originauth_origin_username_lookup_calls_total.fail_authtok_refresh = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="fail_authtok_refresh"}`)
mo.client_originauth_origin_username_lookup_calls_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_originauth_origin_username_lookup_calls_total{result="fail_other_error"}`)
+ mo.client_originauth_eax_username_lookup_duration_seconds = mo.set.NewHistogram(`atlas_api0_client_originauth_eax_username_lookup_duration_seconds`)
+ mo.client_originauth_eax_username_lookup_calls_total.success = mo.set.NewCounter(`atlas_api0_client_originauth_eax_username_lookup_calls_total{result="success"}`)
+ mo.client_originauth_eax_username_lookup_calls_total.notfound = mo.set.NewCounter(`atlas_api0_client_originauth_eax_username_lookup_calls_total{result="notfound"}`)
+ mo.client_originauth_eax_username_lookup_calls_total.fail_update_check = mo.set.NewCounter(`atlas_api0_client_originauth_eax_username_lookup_calls_total{result="fail_update_check"}`)
+ mo.client_originauth_eax_username_lookup_calls_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_originauth_eax_username_lookup_calls_total{result="fail_other_error"}`)
mo.client_authwithserver_requests_total.success = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="success"}`)
mo.client_authwithserver_requests_total.reject_bad_request = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_bad_request"}`)
mo.client_authwithserver_requests_total.reject_versiongate = mo.set.NewCounter(`atlas_api0_client_authwithserver_requests_total{result="reject_versiongate"}`)