Skip to content

Commit 97e1f4d

Browse files
committed
Refactor code and cleanup
1 parent c746ccb commit 97e1f4d

File tree

6 files changed

+139
-63
lines changed

6 files changed

+139
-63
lines changed

appcheck/appcheck.go

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616
package appcheck
1717

1818
import (
19-
"bytes"
2019
"context"
21-
"encoding/json"
2220
"errors"
2321
"fmt"
24-
"net/http"
2522
"strings"
2623
"time"
2724

@@ -36,7 +33,7 @@ var JWKSUrl = "https://firebaseappcheck.googleapis.com/v1beta/jwks"
3633

3734
const appCheckIssuer = "https://firebaseappcheck.googleapis.com/"
3835

39-
const tokenVerifierBaseUrl = "https://firebaseappcheck.googleapis.com"
36+
var verifyTokenURL = "https://firebaseappcheck.googleapis.com/v1beta/projects/%s:verifyAppCheckToken"
4037

4138
var (
4239
// ErrIncorrectAlgorithm is returned when the token is signed with a non-RSA256 algorithm.
@@ -72,9 +69,9 @@ type DecodedAppCheckToken struct {
7269

7370
// Client is the interface for the Firebase App Check service.
7471
type Client struct {
75-
projectID string
76-
jwks *keyfunc.JWKS
77-
tokenVerifierUrl string
72+
projectID string
73+
jwks *keyfunc.JWKS
74+
httpClient *internal.HTTPClient
7875
}
7976

8077
// NewClient creates a new instance of the Firebase App Check Client.
@@ -91,10 +88,15 @@ func NewClient(ctx context.Context, conf *internal.AppCheckConfig) (*Client, err
9188
return nil, err
9289
}
9390

91+
hc, _, err := internal.NewHTTPClient(ctx, conf.Opts...)
92+
if err != nil {
93+
return nil, err
94+
}
95+
9496
return &Client{
95-
projectID: conf.ProjectID,
96-
jwks: jwks,
97-
tokenVerifierUrl: buildTokenVerifierUrl(conf.ProjectID),
97+
projectID: conf.ProjectID,
98+
jwks: jwks,
99+
httpClient: hc,
98100
}, nil
99101
}
100102

@@ -203,42 +205,36 @@ func (c *Client) VerifyToken(token string) (*DecodedAppCheckToken, error) {
203205
// otherwise valid App Check token with an unsupported provider will cause an error to be returned.
204206
//
205207
// If the token was already consumed prior to this call, an error is returned.
206-
func (c *Client) VerifyOneTimeToken(token string) (*DecodedAppCheckToken, error) {
208+
func (c *Client) VerifyOneTimeToken(ctx context.Context, token string) (*DecodedAppCheckToken, error) {
207209
decodedAppCheckToken, err := c.VerifyToken(token)
208210

209211
if err != nil {
210212
return nil, err
211213
}
212214

213-
bodyReader := bytes.NewReader([]byte(fmt.Sprintf(`{"app_check_token":%s}`, token)))
214-
215-
resp, err := http.Post(c.tokenVerifierUrl, "application/json", bodyReader)
216-
217-
if err != nil {
218-
return nil, err
215+
req := &internal.Request{
216+
Method: "POST",
217+
URL: fmt.Sprintf(verifyTokenURL, c.projectID),
218+
Body: internal.NewJSONEntity(map[string]string{
219+
"app_check_token": token,
220+
}),
219221
}
220222

221-
defer resp.Body.Close()
222-
223-
var rb struct {
223+
var resp struct {
224224
AlreadyConsumed bool `json:"alreadyConsumed"`
225225
}
226226

227-
if err := json.NewDecoder(resp.Body).Decode(&rb); err != nil {
227+
if _, err := c.httpClient.DoAndUnmarshal(ctx, req, &resp); err != nil {
228228
return nil, err
229229
}
230230

231-
if rb.AlreadyConsumed {
231+
if resp.AlreadyConsumed {
232232
return nil, ErrTokenAlreadyConsumed
233233
}
234234

235235
return decodedAppCheckToken, nil
236236
}
237237

238-
func buildTokenVerifierUrl(projectId string) string {
239-
return fmt.Sprintf("%s/v1beta/projects/%s:verifyAppCheckToken", tokenVerifierBaseUrl, projectId)
240-
}
241-
242238
func contains(s []string, str string) bool {
243239
for _, v := range s {
244240
if v == str {

appcheck/appcheck_test.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package appcheck
22

33
import (
4+
"bytes"
45
"context"
56
"crypto/rsa"
67
"crypto/x509"
78
"encoding/pem"
89
"errors"
10+
"io"
911
"net/http"
1012
"net/http/httptest"
1113
"os"
@@ -15,6 +17,7 @@ import (
1517
"firebase.google.com/go/v4/internal"
1618
"github.com/golang-jwt/jwt/v4"
1719
"github.com/google/go-cmp/cmp"
20+
"google.golang.org/api/option"
1821
)
1922

2023
func TestVerifyOneTimeToken(t *testing.T) {
@@ -67,24 +70,32 @@ func TestVerifyOneTimeToken(t *testing.T) {
6770
for _, tt := range appCheckVerifyTestsTable {
6871

6972
t.Run(tt.label, func(t *testing.T) {
70-
appCheckVerifyMockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
71-
w.Write([]byte(tt.mockServerResponse))
72-
}))
73+
74+
mockHttpClient := &http.Client{
75+
Transport: &mockHTTPResponse{
76+
Response: http.Response{
77+
StatusCode: 200,
78+
Body: io.NopCloser(bytes.NewBufferString(tt.mockServerResponse)),
79+
},
80+
Err: nil,
81+
},
82+
}
7383

7484
client, err := NewClient(context.Background(), &internal.AppCheckConfig{
7585
ProjectID: projectID,
86+
Opts: []option.ClientOption{
87+
option.WithHTTPClient(mockHttpClient),
88+
},
7689
})
7790

7891
if err != nil {
7992
t.Fatalf("error creating new client: %v", err)
8093
}
8194

82-
client.tokenVerifierUrl = appCheckVerifyMockServer.URL
83-
84-
_, err = client.VerifyOneTimeToken(token)
95+
_, err = client.VerifyOneTimeToken(context.Background(), token)
8596

8697
if !errors.Is(err, tt.expectedError) {
87-
t.Errorf("failed to verify token; Expected: %v, but got: %v", tt.expectedError, err)
98+
t.Errorf("Expected error: %v, but got: %v", tt.expectedError, err)
8899
}
89100
})
90101

@@ -361,3 +372,12 @@ func loadPrivateKey() (*rsa.PrivateKey, error) {
361372
}
362373
return privateKey, nil
363374
}
375+
376+
type mockHTTPResponse struct {
377+
Response http.Response
378+
Err error
379+
}
380+
381+
func (m *mockHTTPResponse) RoundTrip(*http.Request) (*http.Response, error) {
382+
return &m.Response, m.Err
383+
}

firebase.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func (a *App) Messaging(ctx context.Context) (*messaging.Client, error) {
135135
func (a *App) AppCheck(ctx context.Context) (*appcheck.Client, error) {
136136
conf := &internal.AppCheckConfig{
137137
ProjectID: a.projectID,
138+
Opts: a.opts,
138139
}
139140
return appcheck.NewClient(ctx, conf)
140141
}

go.mod

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
11
module firebase.google.com/go/v4
22

3-
go 1.23.0
3+
go 1.24.0
44

55
require (
6-
cloud.google.com/go/firestore v1.18.0
7-
cloud.google.com/go/storage v1.53.0
6+
cloud.google.com/go/firestore v1.20.0
7+
cloud.google.com/go/storage v1.56.0
88
github.com/MicahParks/keyfunc v1.9.0
99
github.com/golang-jwt/jwt/v4 v4.5.2
1010
github.com/google/go-cmp v0.7.0
1111
golang.org/x/oauth2 v0.30.0
12-
google.golang.org/api v0.231.0
12+
google.golang.org/api v0.247.0
1313
google.golang.org/appengine/v2 v2.0.6
1414
)
1515

1616
require (
17-
cel.dev/expr v0.23.1 // indirect
18-
cloud.google.com/go v0.121.0 // indirect
19-
cloud.google.com/go/auth v0.16.1 // indirect
17+
cel.dev/expr v0.24.0 // indirect
18+
cloud.google.com/go v0.121.6 // indirect
19+
cloud.google.com/go/auth v0.16.4 // indirect
2020
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
21-
cloud.google.com/go/compute/metadata v0.6.0 // indirect
21+
cloud.google.com/go/compute/metadata v0.8.0 // indirect
2222
cloud.google.com/go/iam v1.5.2 // indirect
2323
cloud.google.com/go/longrunning v0.6.7 // indirect
2424
cloud.google.com/go/monitoring v1.24.2 // indirect
2525
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
26-
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
27-
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
26+
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect
27+
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect
2828
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2929
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
3030
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
3131
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
3232
github.com/felixge/httpsnoop v1.0.4 // indirect
3333
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
34-
github.com/go-logr/logr v1.4.2 // indirect
34+
github.com/go-logr/logr v1.4.3 // indirect
3535
github.com/go-logr/stdr v1.2.2 // indirect
3636
github.com/golang/protobuf v1.5.4 // indirect
3737
github.com/google/s2a-go v0.1.9 // indirect
3838
github.com/google/uuid v1.6.0 // indirect
3939
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
40-
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
40+
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
4141
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
4242
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
4343
github.com/zeebo/errs v1.4.0 // indirect
4444
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
45-
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
46-
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
47-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
48-
go.opentelemetry.io/otel v1.35.0 // indirect
49-
go.opentelemetry.io/otel/metric v1.35.0 // indirect
50-
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
51-
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
52-
go.opentelemetry.io/otel/trace v1.35.0 // indirect
53-
golang.org/x/crypto v0.40.0 // indirect
54-
golang.org/x/net v0.42.0 // indirect
45+
go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect
46+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
47+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
48+
go.opentelemetry.io/otel v1.36.0 // indirect
49+
go.opentelemetry.io/otel/metric v1.36.0 // indirect
50+
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
51+
go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
52+
go.opentelemetry.io/otel/trace v1.36.0 // indirect
53+
golang.org/x/crypto v0.41.0 // indirect
54+
golang.org/x/net v0.43.0 // indirect
5555
golang.org/x/sync v0.16.0 // indirect
56-
golang.org/x/sys v0.34.0 // indirect
57-
golang.org/x/text v0.27.0 // indirect
58-
golang.org/x/time v0.11.0 // indirect
59-
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
60-
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
61-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250505200425-f936aa4a68b2 // indirect
62-
google.golang.org/grpc v1.72.0 // indirect
63-
google.golang.org/protobuf v1.36.6 // indirect
56+
golang.org/x/sys v0.35.0 // indirect
57+
golang.org/x/text v0.28.0 // indirect
58+
golang.org/x/time v0.12.0 // indirect
59+
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
60+
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect
61+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect
62+
google.golang.org/grpc v1.74.2 // indirect
63+
google.golang.org/protobuf v1.36.7 // indirect
6464
)

0 commit comments

Comments
 (0)