Skip to content

Commit

Permalink
pkg/stryder: Add support for new userName field
Browse files Browse the repository at this point in the history
Added on October 2, 2023.
  • Loading branch information
pg9182 committed Jan 22, 2024
1 parent fdcd4ea commit 4831c45
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
20 changes: 20 additions & 0 deletions pkg/stryder/stryder.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,26 @@ func nucleusAuth(r *http.Response) ([]byte, error) {
return buf, nil
}

// NucleusAuthUsername extracts the username field from the nucleus auth
// response (since October 2, 2023). This field is usually empty for
// unsuccessful responses, but is always present (if not, an error will be
// returned). If resp is empty or invalid, an error will be returned.
func NucleusAuthUsername(resp []byte) (string, error) {
var obj struct {
Username *string `json:"userName,omitempty"`
}
if len(resp) == 0 {
return "", fmt.Errorf("empty or missing nucleus auth response")
}
if err := json.Unmarshal(resp, &obj); err != nil {
return "", fmt.Errorf("%w: invalid nucleus auth response json: %v", ErrStryder, err)
}
if obj.Username == nil {
return "", fmt.Errorf("missing userName field in nucleus auth response %q", string(resp))
}
return *obj.Username, nil
}

func castOr[T any](v any, d T) T {
if x, ok := v.(T); ok {
return x
Expand Down
35 changes: 27 additions & 8 deletions pkg/stryder/stryder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ import (
)

func TestNucleusAuth(t *testing.T) {
testNucleusAuth(t, "Success", `{"token":"...","hasOnlineAccess":"1","expiry":"14399","storeUri":"https://www.origin.com/store/titanfall/titanfall-2/standard-edition"}`, nil)
testNucleusAuth(t, "NoMultiplayer", `{"token":"...","hasOnlineAccess":"0","expiry":"14399","storeUri":"https://www.origin.com/store/titanfall/titanfall-2/standard-edition"}`, ErrMultiplayerNotAllowed)
testNucleusAuth(t, "InvalidToken", `{"success": false, "status": "400", "error": "{"error":"invalid_grant","error_description":"code is invalid","code":100100}"}`, ErrInvalidToken)
testNucleusAuth(t, "StryderBadRequest", `{"success": false, "status": "400", "error": "{"error":"invalid_request","error_description":"code is not issued to this environment","code":100119}"}`, ErrStryder)
testNucleusAuth(t, "StryderBadEndpoint", ``, ErrStryder)
testNucleusAuth(t, "StryderGoAway", "Go away.\n", ErrStryder)
testNucleusAuth(t, "InvalidGame", `{"token":"...","hasOnlineAccess":"1","expiry":"1234","storeUri":"https://www.origin.com/store/titanfall/titanfall-3/future-edition"}`, ErrInvalidGame) // never seen this, but test it
testNucleusAuth(t, "Success", `{"token":"...","hasOnlineAccess":"1","expiry":"14399","storeUri":"https://www.origin.com/store/titanfall/titanfall-2/standard-edition"}`, nil, nil)
testNucleusAuth(t, "SuccessNew", `{"token":"...","hasOnlineAccess":"1","expiry":"14399","storeUri":"https://www.origin.com/store/titanfall/titanfall-2/standard-edition","userName":"test"}`, strPtr("test"), nil)
testNucleusAuth(t, "NoMultiplayer", `{"token":"NO_ONLINE_ACCESS","hasOnlineAccess":"0","expiry":"14399","storeUri":"https://www.origin.com/store/titanfall/titanfall-2/standard-edition"}`, nil, ErrMultiplayerNotAllowed)
testNucleusAuth(t, "NoMultiplayerNew", `{"token":"NO_ONLINE_ACCESS","hasOnlineAccess":"0","expiry":"14399","storeUri":"https://www.origin.com/store/titanfall/titanfall-2/standard-edition","userName":""}`, strPtr(""), ErrMultiplayerNotAllowed)
testNucleusAuth(t, "InvalidToken", `{"success": false, "status": "400", "error": "{"error":"invalid_grant","error_description":"code is invalid","code":100100}"}`, nil, ErrInvalidToken)
testNucleusAuth(t, "StryderBadRequest", `{"success": false, "status": "400", "error": "{"error":"invalid_request","error_description":"code is not issued to this environment","code":100119}"}`, nil, ErrStryder)
testNucleusAuth(t, "StryderBadEndpoint", ``, nil, ErrStryder)
testNucleusAuth(t, "StryderGoAway", "Go away.\n", nil, ErrStryder)
testNucleusAuth(t, "InvalidGame", `{"token":"...","hasOnlineAccess":"1","expiry":"1234","storeUri":"https://www.origin.com/store/titanfall/titanfall-3/future-edition"}`, nil, ErrInvalidGame) // never seen this, but test it
}

func testNucleusAuth(t *testing.T, name, resp string, res error) {
func testNucleusAuth(t *testing.T, name, resp string, username *string, res error) {
t.Run(name, func(t *testing.T) {
buf, err := nucleusAuth(&http.Response{
Status: "200 OK",
Expand All @@ -38,5 +40,22 @@ func testNucleusAuth(t *testing.T, name, resp string, res error) {
t.Errorf("expected error %q, got %q", res, err)
}
}
su, err := NucleusAuthUsername(buf)
if username == nil {
if err == nil {
t.Errorf("expected username error for response %q, got none", string(buf))
}
} else {
if err != nil {
t.Errorf("unexpected username error for response %q: %v", string(buf), err)
}
if su != *username {
t.Errorf("expected username %q for response %q, got %q", *username, string(buf), su)
}
}
})
}

func strPtr(x string) *string {
return &x
}

0 comments on commit 4831c45

Please sign in to comment.