-
Notifications
You must be signed in to change notification settings - Fork 272
feat(appcheck): Add replay protection feature #641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 1 commit
ed9b1fb
b8487ba
6c999a4
604af8d
c746ccb
97e1f4d
3946367
863183a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,80 @@ import ( | |
| "github.com/google/go-cmp/cmp" | ||
| ) | ||
|
|
||
| func TestVerifyTokenWithReplayProtection(t *testing.T) { | ||
|
|
||
| projectID := "project_id" | ||
|
|
||
| ts, err := setupFakeJWKS() | ||
| if err != nil { | ||
| t.Fatalf("error setting up fake JWKS server: %v", err) | ||
| } | ||
| defer ts.Close() | ||
|
|
||
| privateKey, err := loadPrivateKey() | ||
| if err != nil { | ||
| t.Fatalf("error loading private key: %v", err) | ||
| } | ||
|
|
||
| JWKSUrl = ts.URL | ||
| mockTime := time.Now() | ||
|
|
||
| jwtToken := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.RegisteredClaims{ | ||
| Issuer: appCheckIssuer, | ||
| Audience: jwt.ClaimStrings([]string{"projects/" + projectID}), | ||
agbaraka marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Subject: "12345678:app:ID", | ||
agbaraka marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ExpiresAt: jwt.NewNumericDate(mockTime.Add(time.Hour)), | ||
| IssuedAt: jwt.NewNumericDate(mockTime), | ||
| NotBefore: jwt.NewNumericDate(mockTime.Add(-1 * time.Hour)), | ||
| }) | ||
|
|
||
| // kid matches the key ID in testdata/mock.jwks.json, | ||
| // which is the public key matching to the private key | ||
| // in testdata/appcheck_pk.pem. | ||
| jwtToken.Header["kid"] = "FGQdnRlzAmKyKr6-Hg_kMQrBkj_H6i6ADnBQz4OI6BU" | ||
|
|
||
| token, err := jwtToken.SignedString(privateKey) | ||
|
|
||
| if err != nil { | ||
| t.Fatalf("failed to sign token: %v", err) | ||
| } | ||
|
|
||
| appCheckVerifyTestsTable := []struct { | ||
| label string | ||
| mockServerResponse string | ||
| expectedError error | ||
| }{ | ||
| {label: "testWhenAlreadyConsumedResponseIsTrue", mockServerResponse: `{"alreadyConsumed": true}`, expectedError: ErrTokenAlreadyConsumed}, | ||
| {label: "testWhenAlreadyConsumedResponseIsFalse", mockServerResponse: `{"alreadyConsumed": false}`, expectedError: nil}, | ||
| } | ||
|
Comment on lines
+61
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test cases for For example, you could add cases to your test table for:
|
||
|
|
||
| for _, tt := range appCheckVerifyTestsTable { | ||
|
|
||
| t.Run(tt.label, func(t *testing.T) { | ||
| appCheckVerifyMockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
| w.Write([]byte(tt.mockServerResponse)) | ||
| })) | ||
|
|
||
| client, err := NewClient(context.Background(), &internal.AppCheckConfig{ | ||
| ProjectID: projectID, | ||
| }) | ||
|
|
||
| if err != nil { | ||
| t.Fatalf("error creating new client: %v", err) | ||
| } | ||
|
|
||
| client.verifyAppCheckTokenURL = appCheckVerifyMockServer.URL | ||
|
|
||
| _, err = client.VerifyTokenWithReplayProtection(token) | ||
|
|
||
| if !errors.Is(err, tt.expectedError) { | ||
| t.Errorf("failed to verify token; Expected: %v, but got: %v", tt.expectedError, err) | ||
| } | ||
| }) | ||
|
|
||
| } | ||
| } | ||
|
|
||
| func TestVerifyTokenHasValidClaims(t *testing.T) { | ||
| ts, err := setupFakeJWKS() | ||
| if err != nil { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.