Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/auth/handler_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/modules/auth/handler_test.go |
| Original SHA-256 | a9c2eec03aa7600a4f3a20e3962d745f339b4259b1a51c45bfb7dd662db3d754 |
| Git blob SHA | 5a882b8d9a9efac20171d1434b2d09decce5adb3 |
| Reading-copy SHA-256 | a9c2eec03aa7600a4f3a20e3962d745f339b4259b1a51c45bfb7dd662db3d754 |
Recovered source transcript
Download complete source text ↓52 lines · 2.2 KB
package auth
import (
"net/http/httptest"
"strings"
"testing"
)
// 401 MEANS "I DO NOT KNOW WHO YOU ARE", 403 MEANS "I KNOW AND YOU MAY NOT".
//
// This surface answered 403 to both for its whole life, so an expired session was indistinguishable from a
// permission refusal and a client could only guess which had happened. The two are now separated, and this
// test pins which side each case falls on, because the temptation when adding a handler is to copy whichever
// line is nearest.
func TestNoSessionIsUnauthenticatedNotForbidden(t *testing.T) {
w := httptest.NewRecorder()
writeUnauthenticated(w, "no session")
if w.Code != 401 {
t.Errorf("a request with no credential must be 401, got %d", w.Code)
}
// RFC 9110 requires the header on a 401.
auth := w.Header().Get("WWW-Authenticate")
if auth == "" {
t.Error("a 401 must carry WWW-Authenticate")
}
// And it must NOT be a scheme that makes a browser throw its own credential dialog over the application,
// which is exactly what a cookie session exists to avoid.
low := strings.ToLower(auth)
if strings.HasPrefix(low, "basic") || strings.HasPrefix(low, "digest") {
t.Errorf("WWW-Authenticate %q will make a browser show a native login dialog", auth)
}
}
// The structural guard. Every "no session" answer must be 401 and every tenant scoping refusal must stay 403,
// because the difference is what a client keys its retry behaviour on.
func TestAuthStatusCodesStayCorrect(t *testing.T) {
src := readHandlerSource(t)
if strings.Contains(src, `writeError(w, http.StatusForbidden, "no session")`) {
t.Error("a 'no session' case is back to 403; that is unauthenticated, not forbidden")
}
if strings.Contains(src, `http.Error(w, "forbidden", http.StatusForbidden)`) {
t.Error("the session middleware is back to a bare 403 for a missing or invalid cookie")
}
// The genuinely forbidden cases must NOT have been swept into 401 along with them: a caller who is
// authenticated but has no tenant is known and refused, which is 403.
for _, keep := range []string{`"no validated tenant"`, `"no organization context"`} {
if !strings.Contains(src, "http.StatusForbidden, "+keep) {
t.Errorf("%s should remain a 403, the caller is authenticated and merely unscoped", keep)
}
}
}