a73x

internal/oidcprovider/users_test.go

Ref:   Size: 2.8 KiB   History

package oidcprovider

import (
	"path/filepath"
	"testing"
)

func TestLoadUsersMissingFile(t *testing.T) {
	// a missing file is an empty set, not an error: user add before first serve.
	us, err := LoadUsers(filepath.Join(t.TempDir(), "nope.json"))
	if err != nil {
		t.Fatalf("LoadUsers missing: %v", err)
	}
	if len(us.Users) != 0 {
		t.Fatalf("want empty, got %d", len(us.Users))
	}
}

func TestAddUserAndAuthenticate(t *testing.T) {
	path := filepath.Join(t.TempDir(), "users.json")
	if err := AddUser(path, "alex@emery.xyz", "hunter2hunter2"); err != nil {
		t.Fatal(err)
	}
	u, ok := Authenticate(path, "alex@emery.xyz", "hunter2hunter2")
	if !ok {
		t.Fatal("authenticate good password: ok=false")
	}
	if u.Email != "alex@emery.xyz" || u.Sub == "" {
		t.Fatalf("bad user %+v", u)
	}
	if _, ok := Authenticate(path, "alex@emery.xyz", "wrong"); ok {
		t.Fatal("authenticate wrong password: ok=true")
	}
	if _, ok := Authenticate(path, "nobody@emery.xyz", "hunter2hunter2"); ok {
		t.Fatal("authenticate unknown email: ok=true")
	}
}

func TestAddUserReplaceKeepsSub(t *testing.T) {
	// a password change must not rebind the tenant: sub is stable across re-add.
	path := filepath.Join(t.TempDir(), "users.json")
	if err := AddUser(path, "a@b.c", "firstpassword"); err != nil {
		t.Fatal(err)
	}
	before, ok := Authenticate(path, "a@b.c", "firstpassword")
	if !ok {
		t.Fatal("first auth failed")
	}
	if err := AddUser(path, "a@b.c", "secondpassword"); err != nil {
		t.Fatal(err)
	}
	if _, ok := Authenticate(path, "a@b.c", "firstpassword"); ok {
		t.Fatal("old password still authenticates after re-add")
	}
	after, ok := Authenticate(path, "a@b.c", "secondpassword")
	if !ok {
		t.Fatal("new password does not authenticate")
	}
	if before.Sub != after.Sub {
		t.Fatalf("sub rebound: %q -> %q", before.Sub, after.Sub)
	}
	us, _ := LoadUsers(path)
	if len(us.Users) != 1 {
		t.Fatalf("re-add duplicated the row: %d", len(us.Users))
	}
}

func TestRemoveAndList(t *testing.T) {
	path := filepath.Join(t.TempDir(), "users.json")
	for _, e := range []string{"one@x.y", "two@x.y"} {
		if err := AddUser(path, e, "passwordword"); err != nil {
			t.Fatal(err)
		}
	}
	if got := ListUsers(path); len(got) != 2 {
		t.Fatalf("list = %d", len(got))
	}
	if err := RemoveUser(path, "one@x.y"); err != nil {
		t.Fatal(err)
	}
	got := ListUsers(path)
	if len(got) != 1 || got[0].Email != "two@x.y" {
		t.Fatalf("after remove: %+v", got)
	}
	if _, ok := Authenticate(path, "one@x.y", "passwordword"); ok {
		t.Fatal("removed user still authenticates")
	}
}

func TestDistinctSubs(t *testing.T) {
	path := filepath.Join(t.TempDir(), "users.json")
	_ = AddUser(path, "a@x.y", "passwordword")
	_ = AddUser(path, "b@x.y", "passwordword")
	us, _ := LoadUsers(path)
	if us.Users[0].Sub == us.Users[1].Sub {
		t.Fatal("subs collide across users")
	}
}