• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / gotrue / 8135412125

04 Mar 2024 03:34AM UTC coverage: 65.142% (+0.1%) from 65.009%
8135412125

push

github

web-flow
fix: refactor request params to use generics (#1464)

## What kind of change does this PR introduce?
* Introduce a new method `retrieveRequestParams` which makes use of
generics to parse a request
* This will help to simplify parsing a request from:
```go

params := RequestParams{}
body, err := getBodyBytes(r)
if err != nil {
  return nil, badRequestError("Could not read body").WithInternalError(err)
}

if err := json.Unmarshal(body, &params); err != nil {
  return nil, badRequestError("Could not decode request params: %v", err)
}
```
to 
```go
params := &Request{}
err := retrieveRequestParams(req, params)
```

## TODO
- [x] Add type constraint instead of using `any`

48 of 69 new or added lines in 19 files covered. (69.57%)

19 existing lines in 14 files now uncovered.

7806 of 11983 relevant lines covered (65.14%)

59.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.78
/internal/api/helpers.go
1
package api
2

3
import (
4
        "context"
5
        "encoding/json"
6
        "fmt"
7
        "net/http"
8

9
        "github.com/gofrs/uuid"
10
        "github.com/pkg/errors"
11
        "github.com/supabase/auth/internal/conf"
12
        "github.com/supabase/auth/internal/models"
13
        "github.com/supabase/auth/internal/utilities"
14
)
15

16
func addRequestID(globalConfig *conf.GlobalConfiguration) middlewareHandler {
25✔
17
        return func(w http.ResponseWriter, r *http.Request) (context.Context, error) {
650✔
18
                id := ""
625✔
19
                if globalConfig.API.RequestIDHeader != "" {
625✔
20
                        id = r.Header.Get(globalConfig.API.RequestIDHeader)
×
21
                }
×
22
                if id == "" {
1,250✔
23
                        uid := uuid.Must(uuid.NewV4())
625✔
24
                        id = uid.String()
625✔
25
                }
625✔
26

27
                ctx := r.Context()
625✔
28
                ctx = withRequestID(ctx, id)
625✔
29
                return ctx, nil
625✔
30
        }
31
}
32

33
func sendJSON(w http.ResponseWriter, status int, obj interface{}) error {
338✔
34
        w.Header().Set("Content-Type", "application/json")
338✔
35
        b, err := json.Marshal(obj)
338✔
36
        if err != nil {
338✔
37
                return errors.Wrap(err, fmt.Sprintf("Error encoding json response: %v", obj))
×
38
        }
×
39
        w.WriteHeader(status)
338✔
40
        _, err = w.Write(b)
338✔
41
        return err
338✔
42
}
43

44
func isAdmin(u *models.User, config *conf.GlobalConfiguration) bool {
×
45
        return config.JWT.Aud == u.Aud && u.HasRole(config.JWT.AdminGroupName)
×
46
}
×
47

48
func (a *API) requestAud(ctx context.Context, r *http.Request) string {
194✔
49
        config := a.config
194✔
50
        // First check for an audience in the header
194✔
51
        if aud := r.Header.Get(audHeaderName); aud != "" {
194✔
52
                return aud
×
53
        }
×
54

55
        // Then check the token
56
        claims := getClaims(ctx)
194✔
57
        if claims != nil && claims.Audience != "" {
221✔
58
                return claims.Audience
27✔
59
        }
27✔
60

61
        // Finally, return the default if none of the above methods are successful
62
        return config.JWT.Aud
167✔
63
}
64

65
func isStringInSlice(checkValue string, list []string) bool {
84✔
66
        for _, val := range list {
168✔
67
                if val == checkValue {
168✔
68
                        return true
84✔
69
                }
84✔
70
        }
71
        return false
×
72
}
73

74
// getBodyBytes returns a byte array of the request's Body.
75
func getBodyBytes(req *http.Request) ([]byte, error) {
341✔
76
        return utilities.GetBodyBytes(req)
341✔
77
}
341✔
78

79
type RequestParams interface {
80
        AdminUserParams |
81
                CreateSSOProviderParams |
82
                EnrollFactorParams |
83
                GenerateLinkParams |
84
                IdTokenGrantParams |
85
                InviteParams |
86
                OtpParams |
87
                PKCEGrantParams |
88
                PasswordGrantParams |
89
                RecoverParams |
90
                RefreshTokenGrantParams |
91
                ResendConfirmationParams |
92
                SignupParams |
93
                SingleSignOnParams |
94
                SmsParams |
95
                UserUpdateParams |
96
                VerifyFactorParams |
97
                VerifyParams |
98
                adminUserUpdateFactorParams |
99
                struct {
100
                        Email string `json:"email"`
101
                        Phone string `json:"phone"`
102
                }
103
}
104

105
// retrieveRequestParams is a generic method that unmarshals the request body into the params struct provided
106
func retrieveRequestParams[A RequestParams](r *http.Request, params *A) error {
334✔
107
        body, err := getBodyBytes(r)
334✔
108
        if err != nil {
334✔
NEW
109
                return internalServerError("Could not read body into byte slice").WithInternalError(err)
×
NEW
110
        }
×
111
        if err := json.Unmarshal(body, params); err != nil {
335✔
112
                return badRequestError("Could not read request body: %v", err)
1✔
113
        }
1✔
114
        return nil
333✔
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc