Skip to content
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
39 changes: 34 additions & 5 deletions pkg/server/kubedb_inquiry.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (form *KubeDBInquiryInfo) Complete() {

// spamKeywords are terms that never legitimately appear in a KubeDB inquiry;
// their presence marks the submission as spam.
var spamKeywords = []string{"bitcoin", "coinbase"}
var spamKeywords = []string{"bitcoin", "btc", "coinbase", "mining"}

func (form KubeDBInquiryInfo) Validate() error {
if !strings.Contains(form.CustomerEmail, "@") {
Expand All @@ -73,9 +73,10 @@ func (form KubeDBInquiryInfo) Validate() error {
return nil
}

// IsSpam reports whether any field of the inquiry mentions a spam keyword.
// IsSpam reports whether any field of the inquiry mentions a spam keyword or
// contains an emoji character.
func (form KubeDBInquiryInfo) IsSpam() bool {
fields := strings.ToLower(strings.Join([]string{
fields := strings.Join([]string{
form.CustomerName,
form.CustomerCompany,
form.CustomerAddress,
Expand All @@ -86,15 +87,43 @@ func (form KubeDBInquiryInfo) IsSpam() bool {
form.ProjectTimeline,
form.ProfessionalServices,
form.Notes,
}, " "))
}, " ")

lower := strings.ToLower(fields)
for _, keyword := range spamKeywords {
if strings.Contains(fields, keyword) {
if strings.Contains(lower, keyword) {
return true
}
}
return containsEmoji(fields)
}

// containsEmoji reports whether s contains any rune from the common emoji
// blocks of the Unicode standard.
func containsEmoji(s string) bool {
for _, r := range s {
if isEmojiRune(r) {
return true
}
}
return false
}

func isEmojiRune(r rune) bool {
switch {
case r >= 0x1F300 && r <= 0x1FAFF, // symbols, pictographs, emoticons, transport, supplemental symbols
r >= 0x1F1E6 && r <= 0x1F1FF, // regional indicator symbols (flag emoji)
r >= 0x2600 && r <= 0x27BF, // misc symbols and dingbats
r >= 0x2300 && r <= 0x23FF, // misc technical, e.g. ⌚ ⏰
r >= 0x2B00 && r <= 0x2BFF, // misc symbols and arrows, e.g. ⭐
r >= 0xFE00 && r <= 0xFE0F, // variation selectors (emoji presentation)
r == 0x203C || r == 0x2049, // ‼ ⁉
r == 0x2122 || r == 0x2139: // ™ ℹ
return true
}
return false
}

func (s *Server) HandleKubeDBInquiry(info *KubeDBInquiryInfo) error {
go func() {
clients := []*KubeDBInquiryInfo{info}
Expand Down
21 changes: 21 additions & 0 deletions pkg/server/kubedb_inquiry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ func TestKubeDBInquiryInfo_Validate_Spam(t *testing.T) {
},
wantSpam: true,
},
{
name: "emoji in notes",
mutate: func(f *server.KubeDBInquiryInfo) {
f.Notes = "Great product 🚀🔥"
},
wantSpam: true,
},
{
name: "emoji in customer name",
mutate: func(f *server.KubeDBInquiryInfo) {
f.CustomerName = "Jane 😀 Doe"
},
wantSpam: true,
},
{
name: "plain punctuation is not spam",
mutate: func(f *server.KubeDBInquiryInfo) {
f.Notes = "Great product! Looking forward to it :)"
},
wantSpam: false,
},
}

for _, tt := range tests {
Expand Down
Loading