aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-08-07 17:02:10 +0200
committerAleksandr Nogikh <nogikh@google.com>2023-08-08 12:22:00 +0000
commit3c27dfcd35f9666a404f0e34390da6878f544caa (patch)
treeb475b6db9cd3933f6f726b4a293ddbfffa8d3d26
parent9552ae774a39f98cad842755dbc2b79757bcfd0f (diff)
dashboard: support subsystem redirects
There are cases when subsystem names change over time. As we share /namespace/s/name links in our reminder emails, we have to make sure they remain valid. Introduce an old => new name map into the dashboard configuration.
-rw-r--r--dashboard/app/app_test.go3
-rw-r--r--dashboard/app/config.go2
-rw-r--r--dashboard/app/main.go7
-rw-r--r--dashboard/app/main_test.go18
4 files changed, 29 insertions, 1 deletions
diff --git a/dashboard/app/app_test.go b/dashboard/app/app_test.go
index 7deaefe15..88cb8ac1e 100644
--- a/dashboard/app/app_test.go
+++ b/dashboard/app/app_test.go
@@ -309,6 +309,9 @@ var testConfig = &GlobalConfig{
RetestRepros: true,
Subsystems: SubsystemsConfig{
Service: subsystem.MustMakeService(testSubsystems),
+ Redirect: map[string]string{
+ "oldSubsystem": "subsystemA",
+ },
},
},
// The second namespace reporting to the same mailing list.
diff --git a/dashboard/app/config.go b/dashboard/app/config.go
index 88230f9c6..ea123abf7 100644
--- a/dashboard/app/config.go
+++ b/dashboard/app/config.go
@@ -131,6 +131,8 @@ type SubsystemsConfig struct {
Revision int
// Periodic per-subsystem reminders about open bugs.
Reminder *BugListReportingConfig
+ // Maps old subsystem names to new ones.
+ Redirect map[string]string
}
// BugListReportingConfig describes how aggregated reminders about open bugs should be processed.
diff --git a/dashboard/app/main.go b/dashboard/app/main.go
index 7849d0ee5..f6ab7328b 100644
--- a/dashboard/app/main.go
+++ b/dashboard/app/main.go
@@ -511,7 +511,12 @@ func handleSubsystemPage(c context.Context, w http.ResponseWriter, r *http.Reque
}
var subsystem *subsystem.Subsystem
if pos := strings.Index(r.URL.Path, "/s/"); pos != -1 {
- subsystem = service.ByName(r.URL.Path[pos+3:])
+ name := r.URL.Path[pos+3:]
+ if newName := config.Namespaces[hdr.Namespace].Subsystems.Redirect[name]; newName != "" {
+ http.Redirect(w, r, r.URL.Path[:pos+3]+newName, http.StatusMovedPermanently)
+ return nil
+ }
+ subsystem = service.ByName(name)
}
if subsystem == nil {
return fmt.Errorf("%w: the subsystem is not found in the path %v", ErrClientBadRequest, r.URL.Path)
diff --git a/dashboard/app/main_test.go b/dashboard/app/main_test.go
index efbf60ef6..410dd43d4 100644
--- a/dashboard/app/main_test.go
+++ b/dashboard/app/main_test.go
@@ -5,6 +5,8 @@ package main
import (
"bytes"
+ "errors"
+ "net/http"
"testing"
"time"
@@ -336,3 +338,19 @@ func TestAdminJobList(t *testing.T) {
c.expectOK(err)
assert.NotContains(t, string(reply), crash.Title)
}
+
+func TestSubsystemsPageRedirect(t *testing.T) {
+ c := NewCtx(t)
+ defer c.Close()
+
+ // Verify that the normal subsystem page works.
+ _, err := c.AuthGET(AccessAdmin, "/access-public-email/s/subsystemA")
+ c.expectOK(err)
+
+ // Verify that the old subsystem name points to the new one.
+ _, err = c.AuthGET(AccessAdmin, "/access-public-email/s/oldSubsystem")
+ var httpErr *HTTPError
+ c.expectTrue(errors.As(err, &httpErr))
+ c.expectEQ(httpErr.Code, http.StatusMovedPermanently)
+ c.expectEQ(httpErr.Headers["Location"], []string{"/access-public-email/s/subsystemA"})
+}