Skip to content

Commit

Permalink
session: add privacy preserving geolocation accessors
Browse files Browse the repository at this point in the history
The previous diff (#963) has
introduced the concept of an accessor for the resolver IP whose returned
value changes depending on the configured privacy settings.

This is a good programming practice. So, while I am slowly approaching to
the bottom of ooni/explorer#495, I though it was
good yak shaving to implement accessors for every variable for which the
configured privacy settings matter.
  • Loading branch information
bassosimone committed Oct 5, 2020
1 parent 0cb8401 commit d884391
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 30 deletions.
181 changes: 181 additions & 0 deletions generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// +build ignore

package main

import (
"log"
"os"
"text/template"
)

var codeTemplate = template.Must(template.New("code").Parse(`
// Maybe{{ .Name }} is like {{ .Name }} except that we return the real
// value only if the privacy settings allows us. Otherwise, we just
// return the default value, model.Default{{ .Name }}.
func (s *Session) Maybe{{ .Name }}() {{ .Type }} {
out := model.Default{{ .Name }}
if s.privacySettings.{{ .Setting }} {
out = s.{{ .Name }}()
}
return out
}`))

var testTemplate = template.Must(template.New("test").Parse(`
func Test{{ .Name }}Works(t *testing.T) {
sess := &Session{location: &model.LocationInfo{
{{ .LocationInfoName }}: {{ .LocationInfoValue }},
}}
t.Run("with false setting", func(t *testing.T) {
sess.privacySettings.{{ .Setting }} = false
out := sess.Maybe{{ .Name }}()
if out != model.Default{{ .Name }} {
t.Fatal("not the value we expected")
}
})
t.Run("with true setting", func(t *testing.T) {
sess.privacySettings.{{ .Setting }} = true
out := sess.Maybe{{ .Name }}()
if out != {{ .ValueForTesting }} {
t.Fatal("not the value we expected")
}
})
}`))

type Variable struct {
LocationInfoName string
LocationInfoValue string
Name string
Setting string
Type string
ValueForTesting string
}

var Variables = []Variable{{
LocationInfoName: "ProbeIP",
LocationInfoValue: `"8.8.8.8"`,
Name: "ProbeIP",
Setting: "IncludeIP",
Type: "string",
ValueForTesting: `"8.8.8.8"`,
}, {
LocationInfoName: "ASN",
LocationInfoValue: `30722`,
Name: "ProbeASN",
Setting: "IncludeASN",
Type: "uint",
ValueForTesting: `30722`,
}, {
LocationInfoName: "ASN",
LocationInfoValue: `30722`,
Name: "ProbeASNString",
Setting: "IncludeASN",
Type: "string",
ValueForTesting: `"AS30722"`,
}, {
LocationInfoName: "CountryCode",
LocationInfoValue: `"IT"`,
Name: "ProbeCC",
Setting: "IncludeCountry",
Type: "string",
ValueForTesting: `"IT"`,
}, {
LocationInfoName: "NetworkName",
LocationInfoValue: `"Vodafone Italia"`,
Name: "ProbeNetworkName",
Setting: "IncludeASN",
Type: "string",
ValueForTesting: `"Vodafone Italia"`,
}, {
LocationInfoName: "ResolverIP",
LocationInfoValue: `"9.9.9.9"`,
Name: "ResolverIP",
Setting: "IncludeIP",
Type: "string",
ValueForTesting: `"9.9.9.9"`,
}, {
LocationInfoName: "ResolverASN",
LocationInfoValue: `44`,
Name: "ResolverASN",
Setting: "IncludeASN",
Type: "uint",
ValueForTesting: `44`,
}, {
LocationInfoName: "ResolverASN",
LocationInfoValue: `44`,
Name: "ResolverASNString",
Setting: "IncludeASN",
Type: "string",
ValueForTesting: `"AS44"`,
}, {
LocationInfoName: "ResolverNetworkName",
LocationInfoValue: `"Google LLC"`,
Name: "ResolverNetworkName",
Setting: "IncludeASN",
Type: "string",
ValueForTesting: `"Google LLC"`,
}}

func writestring(fp *os.File, s string) {
if _, err := fp.Write([]byte(s)); err != nil {
log.Fatal(err)
}
}

func writeSessionGeneratedGo() {
fp, err := os.Create("session_generated.go")
if err != nil {
log.Fatal(err)
}
writestring(fp, "// Code generated by go generate; DO NOT EDIT.\n")
writestring(fp, "\n")
writestring(fp, "package engine\n")
writestring(fp, "\n")
writestring(fp, "import \"github.com/ooni/probe-engine/model\"\n")
writestring(fp, "\n")
writestring(fp, "//go:generate go run generate.go")
writestring(fp, "\n")
for _, variable := range Variables {
err := codeTemplate.Execute(fp, variable)
if err != nil {
log.Fatal(err)
}
writestring(fp, "\n")
}
if err := fp.Close(); err != nil {
log.Fatal(err)
}
}

func writeSessionGeneratedTestGo() {
fp, err := os.Create("session_generated_test.go")
if err != nil {
log.Fatal(err)
}
writestring(fp, "// Code generated by go generate; DO NOT EDIT.\n")
writestring(fp, "\n")
writestring(fp, "package engine\n")
writestring(fp, "\n")
writestring(fp, "import (\n")
writestring(fp, "\t\"testing\"\n")
writestring(fp, "\n")
writestring(fp, "\t\"github.com/ooni/probe-engine/model\"\n")
writestring(fp, ")\n")
writestring(fp, "\n")
writestring(fp, "//go:generate go run generate.go")
writestring(fp, "\n")
for _, variable := range Variables {
err := testTemplate.Execute(fp, variable)
if err != nil {
log.Fatal(err)
}
writestring(fp, "\n")
}
if err := fp.Close(); err != nil {
log.Fatal(err)
}
}

func main() {
writeSessionGeneratedGo()
writeSessionGeneratedTestGo()
}
4 changes: 2 additions & 2 deletions netx/gocertifi/certifi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion netx/gocertifi/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func main() {
log.Fatal(err)
}

tmpl.Execute(fp, struct {
err = tmpl.Execute(fp, struct {
Timestamp time.Time
URL string
Bundle string
Expand All @@ -85,6 +85,9 @@ func main() {
URL: url,
Bundle: string(bundle),
})
if err != nil {
log.Fatal(err)
}

if err := fp.Close(); err != nil {
log.Fatal(err)
Expand Down
10 changes: 0 additions & 10 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,6 @@ func (s *Session) MaybeLookupBackends() error {
return s.maybeLookupBackends(context.Background())
}

// MaybeResolverIP returns the resolver IP, if we have been given the
// permission to share IPs. Otherwise it returns a canary value.
func (s *Session) MaybeResolverIP() string {
ip := model.DefaultResolverIP
if s.privacySettings.IncludeIP {
ip = s.ResolverIP()
}
return ip
}

// ErrAlreadyUsingProxy indicates that we cannot create a tunnel with
// a specific name because we already configured a proxy.
var ErrAlreadyUsingProxy = errors.New(
Expand Down
106 changes: 106 additions & 0 deletions session_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d884391

Please sign in to comment.