Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse user agent into a human-friendly string on submission #86

Merged
merged 4 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/86.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Parse User-Agent into a human readable format and attach to the report alongside the raw UA string.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.16
require (
github.com/google/go-github v0.0.0-20170401000335-12363ffc1001
github.com/jordan-wright/email v4.0.1-0.20200824153738-3f5bafa1cd84+incompatible
github.com/ua-parser/uap-go v0.0.0-20241012191800-bbb40edc15aa // indirect
github.com/xanzy/go-gitlab v0.50.2
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
gopkg.in/yaml.v2 v2.2.8
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxC
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/jordan-wright/email v4.0.1-0.20200824153738-3f5bafa1cd84+incompatible h1:d60x4RsAHk/UX/0OT8Gc6D7scVvhBbEANpTAWrDhA/I=
github.com/jordan-wright/email v4.0.1-0.20200824153738-3f5bafa1cd84+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -21,6 +23,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/ua-parser/uap-go v0.0.0-20241012191800-bbb40edc15aa h1:VzPR4xFM7HARqNocjdHg75ZL9SAgFtaF3P57ZdDcG6I=
github.com/ua-parser/uap-go v0.0.0-20241012191800-bbb40edc15aa/go.mod h1:BUbeWZiieNxAuuADTBNb3/aeje6on3DhU3rpWsQSB1E=
github.com/xanzy/go-gitlab v0.50.2 h1:Qm/um2Jryuqusc6VmN7iZYVTQVzNynzSiuMJDnCU1wE=
github.com/xanzy/go-gitlab v0.50.2/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand All @@ -45,6 +49,7 @@ google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQ
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
10 changes: 10 additions & 0 deletions submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"encoding/base32"
"encoding/json"
"fmt"
"github.com/ua-parser/uap-go/uaparser"
"io"
"io/ioutil"
"log"
Expand Down Expand Up @@ -291,6 +292,13 @@ func parseRequest(w http.ResponseWriter, req *http.Request, reportDir string) *p
return p
}

var uaParser *uaparser.Parser = uaparser.NewFromSaved()
t3chguy marked this conversation as resolved.
Show resolved Hide resolved

func parseUserAgent(userAgent string) string {
client := uaParser.Parse(userAgent)
return fmt.Sprintf(`%s on %s running on %s device`, client.UserAgent.ToString(), client.Os.ToString(), client.Device.ToString())
}

func parseJSONRequest(w http.ResponseWriter, req *http.Request, reportDir string) (*payload, error) {
var p jsonPayload
if err := json.NewDecoder(req.Body).Decode(&p); err != nil {
Expand Down Expand Up @@ -321,6 +329,7 @@ func parseJSONRequest(w http.ResponseWriter, req *http.Request, reportDir string
parsed.AppName = p.AppName

if p.UserAgent != "" {
parsed.Data["Parsed-User-Agent"] = parseUserAgent(p.UserAgent)
parsed.Data["User-Agent"] = p.UserAgent
}
if p.Version != "" {
Expand Down Expand Up @@ -425,6 +434,7 @@ func formPartToPayload(field, data string, p *payload) {
p.Data["Version"] = data
} else if field == "user_agent" {
p.Data["User-Agent"] = data
p.Data["Parsed-User-Agent"] = parseUserAgent(data)
} else if field == "label" {
p.Labels = append(p.Labels, data)
} else {
Expand Down
29 changes: 27 additions & 2 deletions submit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,9 @@ func checkParsedMultipartUpload(t *testing.T, p *payload) {
if len(p.Logs) != 4 {
t.Errorf("Log length: got %d, want 4", len(p.Logs))
}
if len(p.Data) != 3 {
t.Errorf("Data length: got %d, want 3", len(p.Data))
// One extra data field to account for User Agent being parsed into two fields
if len(p.Data) != 4 {
t.Errorf("Data length: got %d, want 4", len(p.Data))
}
if len(p.Labels) != 0 {
t.Errorf("Labels: got %#v, want []", p.Labels)
Expand Down Expand Up @@ -588,3 +589,27 @@ user_id: id
}
}
}

func TestParseUserAgent(t *testing.T) {
reportDir := mkTempDir(t)
defer os.RemoveAll(reportDir)

body := `{
"app": "riot-web",
"logs": [],
"text": "test message",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.91 Safari/537.3",
"version": "0.9.9"
}`

p, _ := testParsePayload(t, body, "application/json", reportDir)

if p == nil {
t.Fatal("parseRequest returned nil")
}

wanted := "Chrome 130.0.6723 on Windows 10 running on Other device"
if p.Data["Parsed-User-Agent"] != wanted {
t.Errorf("user agent: got %s, want %s", p.Data["Parsed-User-Agent"], wanted)
}
}
Loading