Skip to content
This repository was archived by the owner on Jul 12, 2023. It is now read-only.

Commit 7bbb39f

Browse files
sethvargomikehelmick
authored andcommitted
Do not return 500s from redirect service for missing realms (#1382)
1 parent e57f46a commit 7bbb39f

File tree

19 files changed

+1548
-510
lines changed

19 files changed

+1548
-510
lines changed

cmd/enx-redirect/main.go

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,18 @@ import (
1818
"context"
1919
"crypto/sha1"
2020
"fmt"
21-
"net/http"
2221
"os"
2322
"strconv"
2423

24+
"github.com/google/exposure-notifications-verification-server/internal/routes"
2525
"github.com/google/exposure-notifications-verification-server/pkg/buildinfo"
2626
"github.com/google/exposure-notifications-verification-server/pkg/cache"
2727
"github.com/google/exposure-notifications-verification-server/pkg/config"
28-
"github.com/google/exposure-notifications-verification-server/pkg/controller"
29-
"github.com/google/exposure-notifications-verification-server/pkg/controller/associated"
30-
"github.com/google/exposure-notifications-verification-server/pkg/controller/middleware"
31-
"github.com/google/exposure-notifications-verification-server/pkg/controller/redirect"
32-
"github.com/google/exposure-notifications-verification-server/pkg/render"
3328

3429
"github.com/google/exposure-notifications-server/pkg/logging"
3530
"github.com/google/exposure-notifications-server/pkg/observability"
3631
"github.com/google/exposure-notifications-server/pkg/server"
3732

38-
"github.com/gorilla/mux"
3933
"github.com/sethvargo/go-signalcontext"
4034
)
4135

@@ -77,7 +71,6 @@ func realMain(ctx context.Context) error {
7771
return fmt.Errorf("error initializing observability exporter: %w", err)
7872
}
7973
defer oe.Close()
80-
ctx, obs := middleware.WithObservability(ctx)
8174
logger.Infow("observability exporter", "config", oeConfig)
8275

8376
// Setup cacher
@@ -97,68 +90,13 @@ func realMain(ctx context.Context) error {
9790
}
9891
defer db.Close()
9992

100-
// Create the router
101-
r := mux.NewRouter()
102-
103-
// Common observability context
104-
r.Use(obs)
105-
106-
// Create the renderer
107-
h, err := render.New(ctx, cfg.AssetsPath, cfg.DevMode)
93+
// Setup routes
94+
mux, err := routes.ENXRedirect(ctx, cfg, db, cacher)
10895
if err != nil {
109-
return fmt.Errorf("failed to create renderer: %w", err)
96+
return fmt.Errorf("failed to setup routes: %w", err)
11097
}
11198

112-
// Request ID injection
113-
populateRequestID := middleware.PopulateRequestID(h)
114-
r.Use(populateRequestID)
115-
116-
// Logger injection
117-
populateLogger := middleware.PopulateLogger(logger)
118-
r.Use(populateLogger)
119-
120-
// Install common security headers
121-
r.Use(middleware.SecureHeaders(cfg.DevMode, "html"))
122-
123-
// Enable debug headers
124-
processDebug := middleware.ProcessDebug()
125-
r.Use(processDebug)
126-
127-
// iOS and Android include functionality to associate data between web-apps
128-
// and device apps. Things like handoff between websites and apps, or
129-
// shared credentials are the common usecases. The redirect server
130-
// publishes the metadata needed to share data between the two domains to
131-
// offer a more seemless experience between the website and apps. iOS and
132-
// Android publish specs as to what this format looks like, and both live
133-
// under the /.well-known directory on the server.
134-
//
135-
// Android Specs:
136-
// https://developer.android.com/training/app-links/verify-site-associations
137-
// iOS Specs:
138-
// https://developer.apple.com/documentation/safariservices/supporting_associated_domains
139-
{ // .well-known directory
140-
wk := r.PathPrefix("/.well-known").Subrouter()
141-
142-
// Enable the iOS and Android redirect handler.
143-
assocHandler, err := associated.New(ctx, cfg, db, cacher, h)
144-
if err != nil {
145-
return fmt.Errorf("failed to create associated links handler %w", err)
146-
}
147-
wk.PathPrefix("/apple-app-site-association").Handler(assocHandler.HandleIos()).Methods("GET")
148-
wk.PathPrefix("/assetlinks.json").Handler(assocHandler.HandleAndroid()).Methods("GET")
149-
}
150-
151-
r.Handle("/health", controller.HandleHealthz(ctx, nil, h)).Methods("GET")
152-
153-
redirectController, err := redirect.New(ctx, db, cfg, cacher, h)
154-
if err != nil {
155-
return err
156-
}
157-
r.PathPrefix("/").Handler(redirectController.HandleIndex()).Methods("GET")
158-
159-
mux := http.NewServeMux()
160-
mux.Handle("/", r)
161-
99+
// Run server
162100
srv, err := server.New(cfg.Port)
163101
if err != nil {
164102
return fmt.Errorf("failed to create server: %w", err)

cmd/server/assets/400.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
<body>
99
<main role="main" class="container mt-5">
10-
<h1>Not found</h1>
10+
<h1>Bad request</h1>
1111
<p>
12-
The page you requested does not exist.
12+
That request is not valid.
1313
</p>
1414
</main>
1515
</body>

cmd/server/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,13 @@ func realMain(ctx context.Context) error {
113113
return fmt.Errorf("failed to create firebase auth provider: %w", err)
114114
}
115115

116+
// Setup routes
116117
mux, err := routes.Server(ctx, cfg, db, authProvider, cacher, certificateSigner, limiterStore)
117118
if err != nil {
118119
return fmt.Errorf("failed to setup routes: %w", err)
119120
}
120121

122+
// Run server
121123
srv, err := server.New(cfg.Port)
122124
if err != nil {
123125
return fmt.Errorf("failed to create server: %w", err)

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
988988
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
989989
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
990990
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
991+
github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc=
991992
github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
992993
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
993994
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=

internal/routes/enx_redirect.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package routes
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"net/http"
21+
22+
"github.com/google/exposure-notifications-verification-server/pkg/cache"
23+
"github.com/google/exposure-notifications-verification-server/pkg/config"
24+
"github.com/google/exposure-notifications-verification-server/pkg/controller"
25+
"github.com/google/exposure-notifications-verification-server/pkg/controller/associated"
26+
"github.com/google/exposure-notifications-verification-server/pkg/controller/middleware"
27+
"github.com/google/exposure-notifications-verification-server/pkg/controller/redirect"
28+
"github.com/google/exposure-notifications-verification-server/pkg/database"
29+
"github.com/google/exposure-notifications-verification-server/pkg/render"
30+
31+
"github.com/google/exposure-notifications-server/pkg/logging"
32+
33+
"github.com/gorilla/mux"
34+
)
35+
36+
// ENXRedirect defines routes for the redirector service for ENX.
37+
func ENXRedirect(
38+
ctx context.Context,
39+
cfg *config.RedirectConfig,
40+
db *database.Database,
41+
cacher cache.Cacher,
42+
) (http.Handler, error) {
43+
// Create the router
44+
r := mux.NewRouter()
45+
46+
// Common observability context
47+
ctx, obs := middleware.WithObservability(ctx)
48+
r.Use(obs)
49+
50+
// Create the renderer
51+
h, err := render.New(ctx, cfg.AssetsPath, cfg.DevMode)
52+
if err != nil {
53+
return nil, fmt.Errorf("failed to create renderer: %w", err)
54+
}
55+
56+
// Request ID injection
57+
populateRequestID := middleware.PopulateRequestID(h)
58+
r.Use(populateRequestID)
59+
60+
// Logger injection
61+
populateLogger := middleware.PopulateLogger(logging.FromContext(ctx))
62+
r.Use(populateLogger)
63+
64+
// Install common security headers
65+
r.Use(middleware.SecureHeaders(cfg.DevMode, "html"))
66+
67+
// Enable debug headers
68+
processDebug := middleware.ProcessDebug()
69+
r.Use(processDebug)
70+
71+
// Handle health.
72+
r.Handle("/health", controller.HandleHealthz(ctx, nil, h)).Methods("GET")
73+
74+
// iOS and Android include functionality to associate data between web-apps
75+
// and device apps. Things like handoff between websites and apps, or
76+
// shared credentials are the common usecases. The redirect server
77+
// publishes the metadata needed to share data between the two domains to
78+
// offer a more seemless experience between the website and apps. iOS and
79+
// Android publish specs as to what this format looks like, and both live
80+
// under the /.well-known directory on the server.
81+
//
82+
// Android Specs:
83+
// https://developer.android.com/training/app-links/verify-site-associations
84+
// iOS Specs:
85+
// https://developer.apple.com/documentation/safariservices/supporting_associated_domains
86+
//
87+
{
88+
wk := r.PathPrefix("/.well-known").Subrouter()
89+
90+
// Enable the iOS and Android redirect handler.
91+
assocController, err := associated.New(ctx, cfg, db, cacher, h)
92+
if err != nil {
93+
return nil, fmt.Errorf("failed to create associated links controller: %w", err)
94+
}
95+
wk.PathPrefix("/apple-app-site-association").Handler(assocController.HandleIos()).Methods("GET")
96+
wk.PathPrefix("/assetlinks.json").Handler(assocController.HandleAndroid()).Methods("GET")
97+
}
98+
99+
// Handle redirects.
100+
redirectController, err := redirect.New(ctx, db, cfg, cacher, h)
101+
if err != nil {
102+
return nil, fmt.Errorf("failed to create redirect controller: %w", err)
103+
}
104+
r.PathPrefix("/").Handler(redirectController.HandleIndex()).Methods("GET")
105+
106+
// Wrap the main router in the mutating middleware method. This cannot be
107+
// inserted as middleware because gorilla processes the method before
108+
// middleware.
109+
mux := http.NewServeMux()
110+
mux.Handle("/", middleware.MutateMethod()(r))
111+
return mux, nil
112+
}

pkg/controller/associated/android.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,8 @@ type Target struct {
3333
}
3434

3535
// getAndroidData finds all the android data apps.
36-
func (c *Controller) getAndroidData(region string) ([]AndroidData, error) {
37-
realm, err := c.db.FindRealmByRegion(region)
38-
if err != nil {
39-
return nil, fmt.Errorf("unable to lookup realm: %w", err)
40-
}
41-
42-
apps, err := c.db.ListActiveApps(realm.ID, database.WithAppOS(database.OSTypeAndroid))
36+
func (c *Controller) getAndroidData(realmID uint) ([]AndroidData, error) {
37+
apps, err := c.db.ListActiveApps(realmID, database.WithAppOS(database.OSTypeAndroid))
4338
if err != nil {
4439
return nil, fmt.Errorf("failed to get android data: %w", err)
4540
}

0 commit comments

Comments
 (0)