Skip to content

Commit b868a60

Browse files
committed
fix: redirect to detail page when creating a link that already exists
When attempting to create a link that already exists, redirect to the details page of the existing link to allow for updating. Fixes #160 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
1 parent bcf8006 commit b868a60

3 files changed

Lines changed: 34 additions & 1 deletion

File tree

golink.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ type detailData struct {
667667
Editable bool
668668
Link *Link
669669
XSRF string
670+
Message string
670671
}
671672

672673
func serveDetail(w http.ResponseWriter, r *http.Request) {
@@ -712,6 +713,9 @@ func serveDetail(w http.ResponseWriter, r *http.Request) {
712713
Editable: canEdit,
713714
XSRF: xsrftoken.Generate(xsrfKey, cu.login, link.Short),
714715
}
716+
if r.URL.Query().Get("exists") == "1" {
717+
data.Message = "A link with this short name already exists. You can edit it below."
718+
}
715719
if canEdit && !ownerExists {
716720
data.Link.Owner = cu.login
717721
}
@@ -983,13 +987,24 @@ func serveSave(w http.ResponseWriter, r *http.Request) {
983987

984988
// short name to use for XSRF token.
985989
// For new link creation, the special newShortName value is used.
990+
// For existing links, the link's short name is used. This intentionally
991+
// prevents the home page "create" form from overwriting an existing link;
992+
// to edit an existing link the user must use the detail page edit form
993+
// which generates a token scoped to that link's short name.
986994
tokenShortName := newShortName
987995
if link != nil {
988996
tokenShortName = link.Short
989997
}
990998

991999
if !isRequestAuthorized(r, cu, tokenShortName) {
992-
http.Error(w, "invalid XSRF token", http.StatusBadRequest)
1000+
if link != nil && isRequestAuthorized(r, cu, newShortName) {
1001+
// The user submitted from the home page create form but the link
1002+
// already exists. Redirect to the detail page so they can edit it
1003+
// intentionally rather than accidentally overwriting it.
1004+
http.Redirect(w, r, "/.detail/"+url.PathEscape(short)+"?exists=1", http.StatusSeeOther)
1005+
} else {
1006+
http.Error(w, "invalid XSRF token", http.StatusBadRequest)
1007+
}
9931008
return
9941009
}
9951010

golink_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ func TestServeSave(t *testing.T) {
175175
allowUnknownUsers bool
176176
currentUser func(*http.Request) (user, error)
177177
wantStatus int
178+
wantLocation string
178179
}{
179180
{
180181
name: "missing short",
@@ -235,6 +236,15 @@ func TestServeSave(t *testing.T) {
235236
currentUser: func(*http.Request) (user, error) { return user{}, nil },
236237
wantStatus: http.StatusOK,
237238
},
239+
{
240+
name: "redirect to detail page when creating link that already exists",
241+
short: "who",
242+
xsrf: barXSRF(newShortName),
243+
long: "http://who/updated",
244+
currentUser: func(*http.Request) (user, error) { return user{login: "bar@example.com", isAdmin: true}, nil },
245+
wantStatus: http.StatusSeeOther,
246+
wantLocation: "/.detail/who?exists=1",
247+
},
238248
{
239249
name: "invalid xsrf",
240250
short: "goat",
@@ -270,6 +280,11 @@ func TestServeSave(t *testing.T) {
270280
if w.Code != tt.wantStatus {
271281
t.Errorf("serveSave(%q, %q) = %d; want %d", tt.short, tt.long, w.Code, tt.wantStatus)
272282
}
283+
if tt.wantLocation != "" {
284+
if got := w.Header().Get("Location"); got != tt.wantLocation {
285+
t.Errorf("serveSave(%q, %q) Location = %q; want %q", tt.short, tt.long, got, tt.wantLocation)
286+
}
287+
}
273288
})
274289
}
275290
}

tmpl/detail.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{{ define "main" }}
2+
{{ if .Message }}
3+
<div class="py-2 px-4 mb-6 rounded-md border text-sm border-orange-50 bg-orange-0 text-gray-700">{{ .Message }}</div>
4+
{{ end }}
25
<h2 class="text-xl font-bold pb-2">Link Details</h2>
36

47
{{ if .Editable }}

0 commit comments

Comments
 (0)