Fix single sign-on from the web, and make passwords changeable
Why: two questions about operating this turned up two gaps. "Where do I get the admin password" had no answer once the line scrolled out of the log, and "how do I set up OIDC" ran straight into a sign-in link that could not work. What: - /oidc/login with no parameters now signs a browser in and ends in a session cookie. It previously required the user code of a waiting client, so the link on the web sign-in page always failed. With a code it still approves a device, and the two paths no longer overlap: an empty user code matches no pending device. - POST /api/v1/auth/password, `keeporg passwd`, and a form on /web/vaults. Changing a password requires the current one, and the one-time code when a second factor is enrolled, and revokes that account's other sessions. Until now nothing could change a password, which made the advice printed at first start impossible to follow. - keeporgd -reset-admin, for when that first password was not kept: a new one printed once, any second factor cleared, sessions revoked. It writes the state document directly and says to stop the server first. - The client read stdin through a new buffered reader per prompt, so the first prompt swallowed the rest and anything asking twice could not be scripted. One shared reader now. A prompt for a password being set no longer reads $KEEPORG_PASSWORD either; that variable holds the password you sign in with, and taking it here would have set the new password to the old one. - HANDOVER gains a first-sign-in section and an OIDC setup section covering the redirect URI, the config block, both entry points and how an identity becomes an account. Proved: OIDC now has tests, against a stub provider that serves discovery, authorization, token and userinfo. They cover the web sign-in that was broken, device approval, linking an existing account by username, the refusal when auto_create is off, and a forged callback state. Eight more cover the password change. Checked by hand with the real binaries: the first-start password logs once and works, -reset-admin replaces it while the old one stops working, and `keeporg passwd` changes it from a pipe. Server 0.5.0, desktop clients 0.3.0.
This commit is contained in:
@@ -30,14 +30,27 @@ type harness struct {
|
||||
const adminPassword = "admin-password-1"
|
||||
|
||||
func newHarness(t *testing.T) *harness {
|
||||
return newHarnessWith(t, nil)
|
||||
}
|
||||
|
||||
// newHarnessWith builds a server whose configuration the caller may adjust,
|
||||
// for the cases that need OIDC or a different work factor.
|
||||
func newHarnessWith(t *testing.T, adjust func(*Config)) *harness {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
srv, err := New(Config{
|
||||
// The listener is created first so the server's external URL is the one
|
||||
// it actually answers on, which is what an OIDC redirect needs.
|
||||
ts := httptest.NewUnstartedServer(nil)
|
||||
cfg := Config{
|
||||
DataDir: dir,
|
||||
ExternalURL: "http://keeporg.test",
|
||||
ExternalURL: "http://" + ts.Listener.Addr().String(),
|
||||
MasterKeyFile: filepath.Join(t.TempDir(), "master.key"),
|
||||
VaultKDF: testKDF,
|
||||
}, log.New(io.Discard, "", 0))
|
||||
}
|
||||
if adjust != nil {
|
||||
adjust(&cfg)
|
||||
}
|
||||
srv, err := New(cfg, log.New(io.Discard, "", 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -54,7 +67,8 @@ func newHarness(t *testing.T) *harness {
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ts := httptest.NewServer(srv.Handler())
|
||||
ts.Config = &http.Server{Handler: srv.Handler()}
|
||||
ts.Start()
|
||||
t.Cleanup(ts.Close)
|
||||
return &harness{t: t, srv: srv, http: ts, dataDir: dir}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user