diff options
author | pg9182 <96569817+pg9182@users.noreply.github.com> | 2024-01-22 06:59:50 -0500 |
---|---|---|
committer | pg9182 <96569817+pg9182@users.noreply.github.com> | 2024-01-22 07:06:17 -0500 |
commit | 07194a6bc033689b142e642a85c04a3c3ae2ae7f (patch) | |
tree | b56bf89db9ae4a8f0590db27c359d136db18914e /pkg | |
parent | dfe306faa2fe39fa448eab60ad5afbc202280314 (diff) | |
download | Atlas-07194a6bc033689b142e642a85c04a3c3ae2ae7f.tar.gz Atlas-07194a6bc033689b142e642a85c04a3c3ae2ae7f.zip |
pkg/api/api0: Implement stryder username source
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/api0/client.go | 72 | ||||
-rw-r--r-- | pkg/api/api0/metrics.go | 8 |
2 files changed, 77 insertions, 3 deletions
diff --git a/pkg/api/api0/client.go b/pkg/api/api0/client.go index b62107d..b3fd686 100644 --- a/pkg/api/api0/client.go +++ b/pkg/api/api0/client.go @@ -41,6 +41,17 @@ const ( // Get the username from EAX, but fall back to the Origin API on failure. UsernameSourceEAXOrigin UsernameSource = "eax-origin" + + // Get the username from Stryder (available since October 2, 2023). Note + // that this source only returns usernames for valid tokens. + UsernameSourceStryder UsernameSource = "stryder" + + // Get the username from Stryder, but fall back to EAX on missing/failure. + UsernameSourceStryderEAX UsernameSource = "stryder-eax" + + // Get the username from Stryder, but also check EAX and warn if it's + // different. + UsernameSourceStryderEAXDebug UsernameSource = "stryder-eax-debug" ) type MainMenuPromos struct { @@ -149,6 +160,7 @@ func (h *Handler) handleClientOriginAuth(w http.ResponseWriter, r *http.Request) default: } + var stryderRes []byte if !h.InsecureDevNoCheckPlayerAuth { token := r.URL.Query().Get("token") if token == "" { @@ -162,7 +174,7 @@ func (h *Handler) handleClientOriginAuth(w http.ResponseWriter, r *http.Request) stryderCtx, cancel := context.WithTimeout(r.Context(), time.Second*5) defer cancel() - stryderRes, err := stryder.NucleusAuth(stryderCtx, token, uid) + stryderRes, err = stryder.NucleusAuth(stryderCtx, token, uid) h.m().client_originauth_stryder_auth_duration_seconds.UpdateDuration(stryderStart) if err != nil { switch { @@ -223,7 +235,7 @@ func (h *Handler) handleClientOriginAuth(w http.ResponseWriter, r *http.Request) default: } - username := h.lookupUsername(r, uid) + username := h.lookupUsername(r, uid, stryderRes) select { case <-r.Context().Done(): // check if the request was canceled to avoid making unnecessary requests @@ -302,7 +314,7 @@ func (h *Handler) handleClientOriginAuth(w http.ResponseWriter, r *http.Request) // lookupUsername gets the username for uid according to the configured // UsernameSource, returning an empty string if not found or on error. -func (h *Handler) lookupUsername(r *http.Request, uid uint64) (username string) { +func (h *Handler) lookupUsername(r *http.Request, uid uint64, stryderRes []byte) (username string) { switch h.UsernameSource { case UsernameSourceNone: break @@ -348,6 +360,35 @@ func (h *Handler) lookupUsername(r *http.Request, uid uint64) (username string) Msgf("failed to get username from eax, but got it from origin") } } + case UsernameSourceStryder: + username, _ = h.lookupUsernameStryder(r, uid, stryderRes) + case UsernameSourceStryderEAX: + username, _ = h.lookupUsernameStryder(r, uid, stryderRes) + if username == "" { + if eaxUsername, ok := h.lookupUsernameEAX(r, uid); ok { + username = eaxUsername + hlog.FromRequest(r).Warn(). + Uint64("uid", uid). + Str("eax_username", eaxUsername). + Msgf("failed to get username from stryder, but got it from eax") + } + } + case UsernameSourceStryderEAXDebug: + username, _ = h.lookupUsernameStryder(r, uid, stryderRes) + if eaxUsername, ok := h.lookupUsernameEAX(r, uid); ok { + if eaxUsername != username { + hlog.FromRequest(r).Warn(). + Uint64("uid", uid). + Str("stryder_username", username). + Str("eax_username", eaxUsername). + Msgf("got username from stryder and eax, but they don't match; using the stryder one") + } + } else { + hlog.FromRequest(r).Warn(). + Uint64("uid", uid). + Str("stryder_username", username). + Msgf("got username from stryder, but failed to get username from eax") + } default: hlog.FromRequest(r).Error(). Msgf("unknown username source %q", h.UsernameSource) @@ -467,6 +508,31 @@ func (h *Handler) lookupUsernameEAX(r *http.Request, uid uint64) (username strin return } +// lookupUsernameStryder gets the username for uid from the Stryder response, +// returning an empty string if the username is empty, or false if the +// username is not present in the response or the response is invalid. +func (h *Handler) lookupUsernameStryder(r *http.Request, uid uint64, res []byte) (username string, ok bool) { + select { + case <-r.Context().Done(): // check if the request was canceled to avoid polluting the metrics + return + default: + } + u, err := stryder.NucleusAuthUsername(res) + if err != nil { + hlog.FromRequest(r).Warn(). + Err(err). + Uint64("uid", uid). + Str("username_source", "stryder"). + Msgf("failed to get username from stryder nucleus auth response") + h.m().client_originauth_stryder_username_lookup_calls_total.fail_other_error.Inc() + } else if u == "" { + h.m().client_originauth_stryder_username_lookup_calls_total.notfound.Inc() + } else { + h.m().client_originauth_stryder_username_lookup_calls_total.success.Inc() + } + return u, err == nil +} + 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 ac54944..0c18d0a 100644 --- a/pkg/api/api0/metrics.go +++ b/pkg/api/api0/metrics.go @@ -86,6 +86,11 @@ type apiMetrics struct { fail_update_check *metrics.Counter fail_other_error *metrics.Counter } + client_originauth_stryder_username_lookup_calls_total struct { + success *metrics.Counter + notfound *metrics.Counter + fail_other_error *metrics.Counter + } client_authwithserver_requests_total struct { success *metrics.Counter reject_bad_request *metrics.Counter @@ -275,6 +280,9 @@ func (h *Handler) m() *apiMetrics { 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_originauth_stryder_username_lookup_calls_total.success = mo.set.NewCounter(`atlas_api0_client_originauth_stryder_username_lookup_calls_total{result="success"}`) + mo.client_originauth_stryder_username_lookup_calls_total.notfound = mo.set.NewCounter(`atlas_api0_client_originauth_stryder_username_lookup_calls_total{result="notfound"}`) + mo.client_originauth_stryder_username_lookup_calls_total.fail_other_error = mo.set.NewCounter(`atlas_api0_client_originauth_stryder_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"}`) |