Skip to content

Commit

Permalink
net/url: add URL.Masked()
Browse files Browse the repository at this point in the history
Add method to mask the password in an URL, it's a derived method from
String() that's safe to be shown in logs.
  • Loading branch information
nrxr committed Oct 4, 2019
1 parent 9e6a84f commit 433ea7c
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/net/url/url.go
Expand Up @@ -821,6 +821,17 @@ func (u *URL) String() string {
return buf.String()
}

// Masked returns the same value that calling String() does but it masks the
// password (if exists) of the URL with "xxxxx" so it can be safely used in
// logs.
func (u *URL) Masked() string {
msk := *u
if _, has := msk.User.Password(); has {
msk.User = UserPassword(msk.User.Username(), "xxxxx")
}
return msk.String()
}

// Values maps a string key to a list of values.
// It is typically used for query parameters and form values.
// Unlike in the http.Header map, the keys in a Values map
Expand Down
68 changes: 68 additions & 0 deletions src/net/url/url_test.go
Expand Up @@ -765,6 +765,74 @@ func TestURLString(t *testing.T) {
}
}

var maskedURLTestsPtr = []struct {
url *URL
want string
shouldMask bool
}{
{
url: &URL{
Scheme: "http",
Host: "host.tld",
Path: "this:that",
User: UserPassword("user", "password"),
},
want: "http://user:xxxxx@host.tld/this:that",
shouldMask: true,
},
{
url: &URL{
Scheme: "http",
Host: "host.tld",
Path: "this:that",
User: User("user"),
},
want: "http://user@host.tld/this:that",
shouldMask: false,
},
}

var maskedURLTests = []struct {
url *URL
want string
}{
{
url: &URL{
Scheme: "http",
Host: "host.tld",
Path: "this:that",
User: UserPassword("user", "password"),
},
want: "http://user:xxxxx@host.tld/this:that",
},
{
url: &URL{
Scheme: "http",
Host: "host.tld",
Path: "this:that",
User: User("user"),
},
want: "http://user@host.tld/this:that",
},
}

func TestURLMask(t *testing.T) {
for _, tt := range maskedURLTests {
if got := tt.url.Masked(); got != tt.want {
t.Errorf("%+v.Masked() = %q; want %q", tt.url, got, tt.want)
}
}
for _, tt := range maskedURLTestsPtr {
if got := tt.url.Masked(); got != tt.want {
t.Errorf("%+v.Masked() = %q; want %q", tt.url, got, tt.want)
}

if tt.shouldMask && tt.url.Masked() == tt.url.String() {
t.Errorf("%+v.Masked() password should differ to %+v.String()", tt.url, tt.url)
}
}
}

type EscapeTest struct {
in string
out string
Expand Down

0 comments on commit 433ea7c

Please sign in to comment.