Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Skandalik committed Oct 9, 2024
1 parent da6d87d commit 81b86d6
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 105 deletions.
16 changes: 0 additions & 16 deletions gdpr/go.mod

This file was deleted.

12 changes: 0 additions & 12 deletions gdpr/go.sum

This file was deleted.

30 changes: 15 additions & 15 deletions gdpr/protect_device_id.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package gdpr

import "strings"

const (
ipSeparator = "."
gdprStringHideValue = "*"
gdprIPHideValue = "0"
unknownIPValue = "unknown"
emptyIP = "0"
hiddenRune = '*'
)

// ProtectDeviceID hides last two character from passed device id and returns string with protected value
func ProtectDeviceID(deviceIDValue string) string {
if deviceIDValue == "" {
return deviceIDValue
func ProtectDeviceID(val string) string {
if val == "" {
return val
}

r := []rune(val)
l := len(r)

// If someone passes string with less than 2 characters, we don't protect it.
if l < 2 {
return val
}

splitted := strings.Split(deviceIDValue, "")
l := len(splitted)
splitted[l-1] = gdprStringHideValue
splitted[l-2] = gdprStringHideValue
r[l-1] = hiddenRune
r[l-2] = hiddenRune

return strings.Join(splitted, "")
return string(r)
}
55 changes: 39 additions & 16 deletions gdpr/protect_device_id_test.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,58 @@
package gdpr_test

import (
"strconv"
"testing"

"github.com/stretchr/testify/assert"

"github.com/msales/gox/gdpr"
. "github.com/msales/gox/gdpr"
)

func Test_protector_ProtectDeviceID(t *testing.T) {
func Test_ProtectDeviceID(t *testing.T) {
tests := []struct {
name string
value string
wantProtectedValue string
name string
value string
want string
}{
{
name: "Empty value",
value: "",
wantProtectedValue: "",
name: "empty value",
value: "",
want: "",
},
{
name: "correct value to protect",
value: "some_value",
want: "some_val**",
},
{
name: "only numbers",
value: "12345",
want: "123**",
},
{
name: "string with 2 chars",
value: "11",
want: "**",
},
{
name: "Value to protect",
value: "some_value",
wantProtectedValue: "some_val**",
name: "string with less than 2 chars",
value: "1",
want: "1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
protectedValue := gdpr.ProtectDeviceID(tt.value)

assert.Equal(t, tt.wantProtectedValue, protectedValue)
if got := ProtectDeviceID(tt.value); got != tt.want {
t.Errorf("Got %+v, want %+v", got, tt.want)
}
})
}
}

func BenchmarkProtectDeviceID(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()

for i := 0; i < b.N; i++ {
ProtectDeviceID(strconv.Itoa(i))
}
}
66 changes: 47 additions & 19 deletions gdpr/protect_ip.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,59 @@
package gdpr

import (
"strings"
"encoding/binary"
"net"

"github.com/msales/gox/netx"
)

// ProtectIPV4 hides last octet from passed uint32 IPV4 value and returns string with protected value
func ProtectIPV4(ipValue uint32) string {
if ipValue == 0 {
return netx.UintToIP(ipValue).String()
}

ip := netx.UintToIP(ipValue).String()

return ProtectRawIP(ip)
// IP contains constraint for accepted types of IPs for protection.
type IP interface {
net.IP | netx.IP | uint32 | string
}

// ProtectRawIP hides last octet from ip string value and returns string with protected value
func ProtectRawIP(ipValue string) string {
if ipValue == emptyIP || ipValue == "" || ipValue == unknownIPValue {
return ipValue
// ProtectIP hides last octet from passed uint32 IPV4 value and returns string with protected value
func ProtectIP[T IP](ip T) string {
switch cIP := any(ip).(type) {
// Every other type should end up in this case.
case net.IP:
// if IP is v6, we don't do anything with it.
if cIP.To4() == nil {
return ""
}

// if ip is somehow empty, return empty string
if len(cIP) == 0 {
return ""
}

// change last octet of IP v4 to 0 and guard
cIP[15] = 0
return cIP.String()

// netx.IP is just wrapper over net.IP type, so it's easy to protect against it.
case netx.IP:
return ProtectIP(cIP.ToIP())

// uint32 is number representation of IP used by gox/netx package. 0 is the only edge value to check
case uint32:
if cIP == 0 {
return ""
}

b := make([]byte, 4)
binary.BigEndian.PutUint32(b[:], cIP)
return ProtectIP(net.IPv4(b[0], b[1], b[2], b[3]))

// string is raw representation of IP, downside is that we have to parse it first.
case string:
if cIP == "" {
return ""
}

parsed := net.ParseIP(cIP)
return ProtectIP(parsed)
}

splitted := strings.Split(ipValue, ".")
l := len(splitted)
splitted[l-1] = gdprIPHideValue

return strings.Join(splitted, ipSeparator)
return ""
}
Loading

0 comments on commit 81b86d6

Please sign in to comment.