-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathutils.go
More file actions
139 lines (118 loc) · 3.64 KB
/
Copy pathutils.go
File metadata and controls
139 lines (118 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"fmt"
"log"
"math/rand"
"net"
"net/mail"
"strconv"
"strings"
"time"
"github.com/WiiLink24/nwc24"
"github.com/getsentry/sentry-go"
sentrygin "github.com/getsentry/sentry-go/gin"
"github.com/gin-gonic/gin"
"github.com/logrusorgru/aurora/v4"
)
const (
letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
func GenCGIError(code int, message string) CGIResponse {
return CGIResponse{
code: code,
message: message,
}
}
func (c *CGIResponse) AddMailResponse(index string, code int, message string) {
c.other = append(c.other, KV{
key: fmt.Sprintf("cd%s", index[1:]),
value: strconv.Itoa(code),
}, KV{
key: fmt.Sprintf("msg%s", index[1:]),
value: message,
})
}
// ReportErrorGin helps make errors nicer. First it logs the error to Sentry,
// then prints the error to stdout
func ReportErrorGin(c *gin.Context, err error) {
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.WithScope(func(scope *sentry.Scope) {
hub.CaptureException(err)
})
}
log.Printf("An error has occurred: %s", aurora.Red(err.Error()))
}
// ReportErrorGlobal is for errors that do not occur within a *gin.Context.
func ReportErrorGlobal(err error) {
sentry.CaptureException(err)
log.Printf("An error has occurred: %s", aurora.Red(err.Error()))
}
// generateBoundary returns a boundary string for use in the receive.cgi request.
func generateBoundary() string {
source := rand.NewSource(time.Now().Unix())
val := rand.New(source)
return fmt.Sprintf("%s/%d", time.Now().Format("200601021504"), val.Intn(8999999)+1000000)
}
// validateFriendCode makes sure that the friend code is valid.
// This includes checking its crc and making sure it isn't the default Dolphin hollywood ID.
func validateFriendCode(strId string) bool {
if len(strId) != 16 {
// All Wii Numbers are 16 characters long.
return false
}
id, err := strconv.ParseInt(strId, 10, 64)
if err != nil {
// Not an integer value, therefore not an ID
return false
}
wiiNumber := nwc24.LoadWiiNumber(uint64(id))
if !wiiNumber.CheckWiiNumber() {
// Invalid Wii Number (crc is invalid)
return false
}
return !(wiiNumber.GetHollywoodID() == 0x0403AC68)
}
// From: https://github.com/airylinus/goutils/blob/master/string.go
var src = rand.NewSource(time.Now().UnixNano())
// RandStringBytesMaskImprSrc - generate random string using masking with source
func RandStringBytesMaskImprSrc(n int) string {
b := make([]byte, n)
l := len(letterBytes)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < l {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
// For some reason, the Wii doesn't validate that the email address is valid.
// (i.e. The amazing Sentry error where a user emailed the domain '1679')
// Furthermore, we also check if the domain actually exists.
func validateEmailAddress(email string) bool {
address, err := mail.ParseAddress(email)
if err != nil {
return false
}
parts := strings.Split(address.Address, "@")
if len(parts) != 2 {
return false
}
domain := parts[1]
// Search the MX records for the supposed domain.
records, err := net.LookupMX(domain)
if err != nil || len(records) == 0 {
// No email servers.
return false
}
return true
}