mesh/delivery-group group feat/774-l3-reland rejected: composed together: the checker's verdict at the members' heads (b48c90fea31f): integration: mesh-self-ch…
mesh/delivery closed: a newer head of the same pull request
mesh/check failed: integration: mesh-self-check/cmd/mesh-self-check.TestTheSelfCheckWholeRunsOnTheBus: the run answered {Run:doctor-1793351737-1 At:20…
One commit with exactly the tree of the reviewed head35b4509c0a, on main12c2574c9d, so two compiled programs added and removed on the branch leave no trace in history (issue 1577).
267 lines
9.7 KiB
Go
267 lines
9.7 KiB
Go
package main
|
|
|
|
// What holds keycloak to the `oidc-client` provision: one confidential client per consumer, under
|
|
// the id and secret the mesh gave, redirecting only to the consumer's own callback under the names
|
|
// the mesh composed; made once and brought back on every apply; and a client the mesh did not make —
|
|
// same id or not — never adopted, changed or deleted. Ported from test/oidc.test.ts.
|
|
|
|
import (
|
|
"encoding/json"
|
|
"git.novox.be/novox/mesh-sdk/go/provider/harness"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func oidcWorld(t *testing.T) (*fakeKeycloak, OidcClients) {
|
|
f := newFakeKeycloak(t, "Novox", "pw")
|
|
return f, OidcClients{KC: f.client("pw"), Realm: "Novox"}
|
|
}
|
|
|
|
// grafana is a dashboard on the home server, as the mesh hands it to the provisioner.
|
|
func grafana(secret string, extra map[string]any) harness.Provision {
|
|
values := map[string]any{"label": "grafana", "endpoint": "web", "port": 20010.0, "callback": "/login/generic_oauth",
|
|
"name": "grafana.example.org", "internal-name": "grafana.home.internal"}
|
|
for k, v := range extra {
|
|
values[k] = v
|
|
}
|
|
return harness.Provision{As: "mesh_home_grafana", Password: secret, Consumer: "home", Values: values}
|
|
}
|
|
|
|
func only(t *testing.T, f *fakeKeycloak, clientID string) Rep {
|
|
t.Helper()
|
|
var found []Rep
|
|
for _, c := range f.clients {
|
|
if c["clientId"] == clientID {
|
|
found = append(found, c)
|
|
}
|
|
}
|
|
if len(found) != 1 {
|
|
t.Fatalf("exactly one client %s, found %d", clientID, len(found))
|
|
}
|
|
return found[0]
|
|
}
|
|
|
|
func mustHold(t *testing.T, o OidcClients, p harness.Provision, want bool) {
|
|
t.Helper()
|
|
held, err := o.Holds(ctx, p)
|
|
if err != nil || held != want {
|
|
t.Fatalf("holds = %v, %v; want %v", held, err, want)
|
|
}
|
|
}
|
|
|
|
func TestTheRealmIsReadOutOfTheIssuer(t *testing.T) {
|
|
for issuer, want := range map[string]string{
|
|
"https://id.example.org/realms/Novox": "Novox",
|
|
"https://id.example.org/realms/Novox/": "Novox",
|
|
"http://127.0.0.1:18500/realms/master": "master",
|
|
} {
|
|
if got, err := RealmOf(issuer); err != nil || got != want {
|
|
t.Errorf("%s: %q %v", issuer, got, err)
|
|
}
|
|
}
|
|
if _, err := RealmOf("https://id.example.org"); err == nil || !strings.Contains(err.Error(), "realms") {
|
|
t.Error(err)
|
|
}
|
|
if _, err := RealmOf("keycloak"); err == nil || !strings.Contains(err.Error(), "not a URL") {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestTheRedirectIsTheCallbackUnderEveryComposedName(t *testing.T) {
|
|
root, redirects, err := RedirectsOf(grafana("s", nil).Values)
|
|
if err != nil || root != "https://grafana.example.org" || !reflect.DeepEqual(redirects,
|
|
[]string{"https://grafana.example.org/login/generic_oauth", "https://grafana.home.internal/login/generic_oauth"}) {
|
|
t.Fatal(root, redirects, err)
|
|
}
|
|
if _, r, _ := RedirectsOf(map[string]any{"callback": "/cb", "internal-name": "x.home.internal"}); !reflect.DeepEqual(r, []string{"https://x.home.internal/cb"}) {
|
|
t.Fatal(r)
|
|
}
|
|
for _, values := range []map[string]any{{"name": "g"}, {"name": "g", "callback": "login"}} {
|
|
if _, _, err := RedirectsOf(values); err == nil || !strings.Contains(err.Error(), "callback") {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
if _, _, err := RedirectsOf(map[string]any{"callback": "/cb"}); err == nil || !strings.Contains(err.Error(), "label") {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestAConsumerIsGivenOneConfidentialClient(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
if done, err := o.Ensure(ctx, grafana("s3cret", nil)); err != nil || done != "created" {
|
|
t.Fatal(done, err)
|
|
}
|
|
c := only(t, f, "mesh_home_grafana")
|
|
for k, v := range map[string]any{"publicClient": false, "clientAuthenticatorType": "client-secret", "secret": "s3cret",
|
|
"enabled": true, "standardFlowEnabled": true, "directAccessGrantsEnabled": false, "implicitFlowEnabled": false} {
|
|
if c[k] != v {
|
|
t.Errorf("%s = %v, want %v", k, c[k], v)
|
|
}
|
|
}
|
|
if attributes(c)[Mark] != "true" || len(c["protocolMappers"].([]any)) != 1 {
|
|
t.Fatal(c)
|
|
}
|
|
mustHold(t, o, grafana("s3cret", nil), true)
|
|
}
|
|
|
|
func TestApplyingTheSameGrantAgainMakesNoSecondClient(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
o.Ensure(ctx, grafana("s", nil))
|
|
for i := 0; i < 2; i++ {
|
|
if done, err := o.Ensure(ctx, grafana("s", nil)); err != nil || done != "updated" {
|
|
t.Fatal(done, err)
|
|
}
|
|
}
|
|
if n := len(only(t, f, "mesh_home_grafana")["protocolMappers"].([]any)); n != 1 {
|
|
t.Fatalf("the roles mapper was added %d times", n)
|
|
}
|
|
}
|
|
|
|
func TestANewSecretIsAppliedInPlaceAndWhatTheMeshDoesNotOwnSurvives(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
o.Ensure(ctx, grafana("s", nil))
|
|
c := only(t, f, "mesh_home_grafana")
|
|
id := c["id"]
|
|
c["consentRequired"] = true
|
|
attributes(c)["post.logout.redirect.uris"] = "+"
|
|
|
|
mustHold(t, o, grafana("rotated", nil), false)
|
|
if _, err := o.Ensure(ctx, grafana("rotated", map[string]any{"name": "dash.example.org"})); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
c = only(t, f, "mesh_home_grafana")
|
|
if c["id"] != id || c["secret"] != "rotated" || c["rootUrl"] != "https://dash.example.org" ||
|
|
c["consentRequired"] != true || attributes(c)["post.logout.redirect.uris"] != "+" || attributes(c)[Mark] != "true" {
|
|
raw, _ := json.Marshal(c)
|
|
t.Fatal(string(raw))
|
|
}
|
|
mustHold(t, o, grafana("rotated", map[string]any{"name": "dash.example.org"}), true)
|
|
}
|
|
|
|
func TestAClientEditedBehindTheMeshsBackIsNotHeldAndIsMadeWhole(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
o.Ensure(ctx, grafana("s", nil))
|
|
only(t, f, "mesh_home_grafana")["redirectUris"] = []any{"*"}
|
|
mustHold(t, o, grafana("s", nil), false)
|
|
o.Ensure(ctx, grafana("s", nil))
|
|
mustHold(t, o, grafana("s", nil), true)
|
|
|
|
only(t, f, "mesh_home_grafana")["protocolMappers"] = []any{}
|
|
mustHold(t, o, grafana("s", nil), false)
|
|
o.Ensure(ctx, grafana("s", nil))
|
|
mustHold(t, o, grafana("s", nil), true)
|
|
|
|
f.clients = map[string]Rep{}
|
|
mustHold(t, o, grafana("s", nil), false)
|
|
}
|
|
|
|
func TestAClientTheMeshDidNotMakeIsRefusedAndLeftAlone(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
f.clients["theirs"] = Rep{"id": "theirs", "clientId": "mesh_home_grafana", "secret": "their-secret", "redirectUris": []any{"*"}}
|
|
before, _ := json.Marshal(f.clients["theirs"])
|
|
from := len(f.calls)
|
|
if _, err := o.Ensure(ctx, grafana("s", nil)); err == nil || !strings.Contains(err.Error(), "did not make") {
|
|
t.Fatal(err)
|
|
}
|
|
after, _ := json.Marshal(f.clients["theirs"])
|
|
if string(before) != string(after) {
|
|
t.Fatal("changed")
|
|
}
|
|
for _, c := range f.calls[from:] {
|
|
if !strings.HasPrefix(c, "GET") && !strings.HasPrefix(c, "POST /realms/master") {
|
|
t.Fatalf("wrote: %v", f.calls[from:])
|
|
}
|
|
}
|
|
mustHold(t, o, grafana("s", nil), false)
|
|
if done, _ := o.Retire(ctx, "mesh_home_grafana", "x", time.Now()); done != "not ours" || f.clients["theirs"]["enabled"] == false {
|
|
t.Fatal(done)
|
|
}
|
|
if err := o.Delete(ctx, "mesh_home_grafana"); err == nil || f.clients["theirs"] == nil {
|
|
t.Fatal("deleted a client the mesh did not make")
|
|
}
|
|
if inv, _ := o.Inventory(ctx); len(inv.Active)+len(inv.Retired) != 0 {
|
|
t.Fatalf("listed a client the mesh did not make: %+v", inv)
|
|
}
|
|
}
|
|
|
|
// Retired is its secret removed, disabled and marked, everything else kept (ADR 0570 clause 5); asked for again it is enabled as it was; only
|
|
// a deletion removes it, and never while enabled (novox/hq ADR 0230).
|
|
func TestARetiredClientIsDisabledKeptAndEnabledAgainAsItWas(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
p := grafana("s", nil)
|
|
if _, err := o.Ensure(ctx, p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var id string
|
|
for k := range f.clients {
|
|
id = k
|
|
}
|
|
f.clients[id]["description2"] = "an operator's own field"
|
|
at := time.Date(2026, 10, 6, 12, 0, 0, 0, time.UTC)
|
|
if done, err := o.Retire(ctx, "mesh_home_grafana", "the mesh stopped asking for it", at); done != "retired" || err != nil {
|
|
t.Fatal(done, err)
|
|
}
|
|
c := f.clients[id]
|
|
if c["enabled"] != false || c["secret"] == "s" || c["secret"] == "" || attributes(c)[MarkRetired] != "2026-10-06T12:00:00Z" ||
|
|
attributes(c)[MarkRetiredWhy] != "the mesh stopped asking for it" || c["description2"] == nil {
|
|
t.Fatalf("%v", c)
|
|
}
|
|
mustHold(t, o, p, false)
|
|
inv, err := o.Inventory(ctx)
|
|
if err != nil || len(inv.Active) != 0 || len(inv.Retired) != 1 || !inv.Retired[0].RetiredAt.Equal(at) ||
|
|
inv.Retired[0].Consumer != "mesh_home_grafana" {
|
|
t.Fatalf("%+v %v", inv, err)
|
|
}
|
|
// Asked for again: enabled, unmarked, the same client.
|
|
if _, err := o.Ensure(ctx, p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
c = f.clients[id]
|
|
if c["enabled"] != true || c["secret"] != "s" || attributes(c)[MarkRetired] != nil || attributes(c)[MarkRetiredWhy] != nil || c["description2"] == nil {
|
|
t.Fatalf("%v", c)
|
|
}
|
|
mustHold(t, o, p, true)
|
|
if inv, _ := o.Inventory(ctx); len(inv.Active) != 1 || len(inv.Retired) != 0 {
|
|
t.Fatalf("%+v", inv)
|
|
}
|
|
// Never deleted while enabled; deleted once retired; absent is no error.
|
|
if err := o.Delete(ctx, "mesh_home_grafana"); err == nil || len(f.clients) != 1 {
|
|
t.Fatal("deleted an enabled client")
|
|
}
|
|
o.Retire(ctx, "mesh_home_grafana", "again", at)
|
|
if err := o.Delete(ctx, "mesh_home_grafana"); err != nil || len(f.clients) != 0 {
|
|
t.Fatal(err, f.clients)
|
|
}
|
|
if err := o.Delete(ctx, "mesh_home_grafana"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if done, err := o.Retire(ctx, "mesh_home_grafana", "x", at); done != "absent" || err != nil {
|
|
t.Fatal(done, err)
|
|
}
|
|
}
|
|
|
|
// A client the mesh made and found disabled without the mark — before ADR 0230 — is listed retired
|
|
// with no date, which the loop adopts.
|
|
func TestAClientFoundDisabledIsListedRetiredWithoutADate(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
o.Ensure(ctx, grafana("s", nil))
|
|
for _, c := range f.clients {
|
|
c["enabled"] = false
|
|
}
|
|
inv, err := o.Inventory(ctx)
|
|
if err != nil || len(inv.Retired) != 1 || !inv.Retired[0].RetiredAt.IsZero() {
|
|
t.Fatalf("%+v %v", inv, err)
|
|
}
|
|
}
|
|
|
|
func TestAContributionWithNoCallbackMakesNoClient(t *testing.T) {
|
|
f, o := oidcWorld(t)
|
|
p := grafana("s", nil)
|
|
p.Values = map[string]any{"name": "grafana.example.org"}
|
|
if _, err := o.Ensure(ctx, p); err == nil || !strings.Contains(err.Error(), "callback") || len(f.clients) != 0 {
|
|
t.Fatal(err)
|
|
}
|
|
}
|