Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 36m ago 4b8c9e1d
history blame raw 3.2 KiB
1package web
2
3import (
4 "net/http"
5 "net/http/httptest"
6 "testing"
7
8 "rodent.software/vole/forge/config"
9 "rodent.software/vole/forge/identity"
10)
11
12func TestDevLoginRefusesANonLoopbackListener(t *testing.T) {
13 w := &Web{}
14 err := w.enableDevLogin(&config.Config{HTTPAddr: "0.0.0.0:8080", DevLogin: "keenan"})
15 if err == nil {
16 t.Fatal("dev_login accepted a listener that is not loopback")
17 }
18}
19
20// TestDevLoginRefusesAPublicInstance: development login is a credential-free
21// session, so it may not be configured on an instance that is reachable by name.
22func TestDevLoginRefusesAPublicInstance(t *testing.T) {
23 for _, cfg := range []*config.Config{
24 {HTTPAddr: "127.0.0.1:8080", DevLogin: "keenan", PublicURL: "https://forge.example.com"},
25 {HTTPAddr: "127.0.0.1:8080", DevLogin: "keenan", HTTPSAddr: ":443"},
26 } {
27 if err := (&Web{}).enableDevLogin(cfg); err == nil {
28 t.Fatalf("dev_login accepted an instance with public_url %q / https_addr %q", cfg.PublicURL, cfg.HTTPSAddr)
29 }
30 }
31}
32
33func TestDevLoginRequestOnlyFromTheConfiguredListener(t *testing.T) {
34 cfg := &config.Config{HTTPAddr: "127.0.0.1:8080", DevLogin: "keenan", DevOnly: true}
35 w := &Web{Cfg: cfg, devAccount: &identity.Account{Name: "keenan", Status: "active"}}
36
37 // The request a development browser makes.
38 r := httptest.NewRequest("GET", "http://127.0.0.1:8080/", nil)
39 r.RemoteAddr = "127.0.0.1:5000"
40 if !w.devLoginRequest(r) {
41 t.Fatal("dev login did not apply to a request to the configured loopback listener")
42 }
43
44 // A loopback proxy forwarding a public name.
45 r.Host = "forge.example.com"
46 if w.devLoginRequest(r) {
47 t.Fatal("dev login applied to a non-loopback Host through a local proxy")
48 }
49
50 // A proxy that rewrites Host to a loopback name, which the old check allowed.
51 r.Host = "127.0.0.1"
52 if w.devLoginRequest(r) {
53 t.Fatal("dev login applied to a proxy-rewritten Host without the configured port")
54 }
55 r.Host = "127.0.0.1:8080"
56 if !w.devLoginRequest(r) {
57 t.Fatal("dev login stopped applying to the configured listener")
58 }
59
60 // And a proxy that keeps Host intact but announces itself.
61 r.Header.Set("X-Forwarded-For", "203.0.113.9")
62 if w.devLoginRequest(r) {
63 t.Fatal("dev login applied to a proxied request")
64 }
65}
66
67// TestDevLoginIgnoresANonLoopbackPeer: a listener bound to 0.0.0.0 accepts remote
68// connections, and no Host header makes those local.
69func TestDevLoginIgnoresANonLoopbackPeer(t *testing.T) {
70 cfg := &config.Config{HTTPAddr: "127.0.0.1:8080", DevLogin: "keenan", DevOnly: true}
71 w := &Web{Cfg: cfg, devAccount: &identity.Account{Name: "keenan", Status: "active"}}
72 r := httptest.NewRequest("GET", "http://127.0.0.1:8080/", nil)
73 r.RemoteAddr = "198.51.100.7:5000"
74 if w.devLoginRequest(r) {
75 t.Fatal("dev login applied to a remote address")
76 }
77}
78
79func TestDevLoginOptOutCookie(t *testing.T) {
80 cfg := &config.Config{HTTPAddr: "127.0.0.1:8080", DevLogin: "keenan", DevOnly: true}
81 w := &Web{Cfg: cfg, devAccount: &identity.Account{Name: "keenan", Status: "active"}}
82 r := httptest.NewRequest("GET", "http://127.0.0.1:8080/", nil)
83 r.RemoteAddr = "127.0.0.1:5000"
84 r.AddCookie(&http.Cookie{Name: devOffCookieName, Value: "1"})
85 if w.devLoginRequest(r) {
86 t.Fatal("dev login ignored the opt-out cookie")
87 }
88}
89