fix: address final review findings for master/agent phase 1 (#6)
- inventory: resolve the image reference via ContainerInspect when a moved tag makes ContainerList report the image ID - store: allow reusing a revoked agent's name (partial unique index) and mark the revoked agent's compose/container services removed - web: publish a services event on revoke; no-store on the one-time token page - webauth: reject empty OIDC state; accept the CSRF form token from the body only - agent conn: bound the WebSocket handshake to 30s - hub: log agent_replaced when a connection replaces an older one
This commit is contained in:
@@ -84,7 +84,9 @@ func startLogin(t *testing.T, a *Auth) (*http.Cookie, string) {
|
||||
|
||||
func callback(a *Auth, flow *http.Cookie, state string) *httptest.ResponseRecorder {
|
||||
req := httptest.NewRequest(http.MethodGet, "/auth/callback?code=c&state="+url.QueryEscape(state), nil)
|
||||
req.AddCookie(flow)
|
||||
if flow != nil {
|
||||
req.AddCookie(flow)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
a.Callback(rec, req)
|
||||
return rec
|
||||
@@ -98,11 +100,25 @@ func TestLogin_SetsFlowCookieAndRedirects(t *testing.T) {
|
||||
assert.NotEmpty(t, state)
|
||||
}
|
||||
|
||||
func TestCallback_StateMismatchRejected(t *testing.T) {
|
||||
a := newAuth(&fakeProvider{}, newFakeStore())
|
||||
func TestCallback_InvalidStateRejected(t *testing.T) {
|
||||
a := newAuth(&fakeProvider{claims: Claims{Subject: "u", Groups: []string{"updater-admins"}}}, newFakeStore())
|
||||
flow, _ := startLogin(t, a)
|
||||
rec := callback(a, flow, "forged")
|
||||
assert.Equal(t, http.StatusBadRequest, rec.Code)
|
||||
emptyStateFlow := &http.Cookie{Name: flowCookieName, Value: ".verifier"}
|
||||
cases := []struct {
|
||||
name string
|
||||
flow *http.Cookie
|
||||
state string
|
||||
}{
|
||||
{"state mismatch", flow, "forged"},
|
||||
{"empty state in cookie and query", emptyStateFlow, ""},
|
||||
{"missing flow cookie", nil, ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
rec := callback(a, c.flow, c.state)
|
||||
assert.Equal(t, http.StatusBadRequest, rec.Code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallback_UserOutsideGroupForbidden(t *testing.T) {
|
||||
@@ -197,6 +213,12 @@ func TestRequire(t *testing.T) {
|
||||
r.AddCookie(&http.Cookie{Name: sessionCookieName, Value: "live"})
|
||||
return r
|
||||
}(), http.StatusNoContent, [2]string{}},
|
||||
{"POST with CSRF only in query string", func() *http.Request {
|
||||
r := httptest.NewRequest(http.MethodPost, "/agents?csrf_token=tok", strings.NewReader("name=x"))
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
r.AddCookie(&http.Cookie{Name: sessionCookieName, Value: "live"})
|
||||
return r
|
||||
}(), http.StatusForbidden, [2]string{}},
|
||||
{"GET with session", protectedRequest(http.MethodGet, "/", "live"), http.StatusNoContent, [2]string{}},
|
||||
}
|
||||
for _, c := range cases {
|
||||
|
||||
Reference in New Issue
Block a user