aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpg9182 <96569817+pg9182@users.noreply.github.com>2024-01-22 06:59:50 -0500
committerpg9182 <96569817+pg9182@users.noreply.github.com>2024-01-22 07:06:17 -0500
commit07194a6bc033689b142e642a85c04a3c3ae2ae7f (patch)
treeb56bf89db9ae4a8f0590db27c359d136db18914e
parentdfe306faa2fe39fa448eab60ad5afbc202280314 (diff)
downloadAtlas-07194a6bc033689b142e642a85c04a3c3ae2ae7f.tar.gz
Atlas-07194a6bc033689b142e642a85c04a3c3ae2ae7f.zip
pkg/api/api0: Implement stryder username source
-rw-r--r--pkg/api/api0/client.go72
-rw-r--r--pkg/api/api0/metrics.go8
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"}`)