1package helpers
2
3import (
4 crand "crypto/rand"
5 "encoding/hex"
6 "errors"
7 "math/rand"
8 "net/url"
9
10 "github.com/labstack/echo/v4"
11 "github.com/lestrrat-go/jwx/v2/jwk"
12)
13
14// This will confirm to the regex in the application if 5 chars are used for each side of the -
15// /^[A-Z2-7]{5}-[A-Z2-7]{5}$/
16var letters = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")
17
18func InputError(e echo.Context, custom *string) error {
19 msg := "InvalidRequest"
20 if custom != nil {
21 msg = *custom
22 }
23 return genericError(e, 400, msg)
24}
25
26func ServerError(e echo.Context, suffix *string) error {
27 msg := "Internal server error"
28 if suffix != nil {
29 msg += ". " + *suffix
30 }
31 return genericError(e, 400, msg)
32}
33
34func genericError(e echo.Context, code int, msg string) error {
35 return e.JSON(code, map[string]string{
36 "error": msg,
37 })
38}
39
40func RandomVarchar(length int) string {
41 b := make([]rune, length)
42 for i := range b {
43 b[i] = letters[rand.Intn(len(letters))]
44 }
45 return string(b)
46}
47
48func RandomHex(n int) (string, error) {
49 bytes := make([]byte, n)
50 if _, err := crand.Read(bytes); err != nil {
51 return "", err
52 }
53 return hex.EncodeToString(bytes), nil
54}
55
56func RandomBytes(n int) []byte {
57 bs := make([]byte, n)
58 crand.Read(bs)
59 return bs
60}
61
62func ParseJWKFromBytes(b []byte) (jwk.Key, error) {
63 return jwk.ParseKey(b)
64}
65
66func OauthParseHtu(htu string) (string, error) {
67 u, err := url.Parse(htu)
68 if err != nil {
69 return "", errors.New("`htu` is not a valid URL")
70 }
71
72 if u.User != nil {
73 _, containsPass := u.User.Password()
74 if u.User.Username() != "" || containsPass {
75 return "", errors.New("`htu` must not contain credentials")
76 }
77 }
78
79 if u.Scheme != "http" && u.Scheme != "https" {
80 return "", errors.New("`htu` must be http or https")
81 }
82
83 return OauthNormalizeHtu(u), nil
84}
85
86func OauthNormalizeHtu(u *url.URL) string {
87 return u.Scheme + "://" + u.Host + u.RawPath
88}