File size: 3,157 Bytes
5cb63c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { describe, expect, it } from "vitest";
import {
  defineStableChannelIngressIdentity,
  identityEntryAuthenticationClassifier,
} from "./runtime-identity.js";
import type { ChannelIngressIdentityDescriptor } from "./runtime-types.js";

describe("identityEntryAuthenticationClassifier", () => {
  const identity = defineStableChannelIngressIdentity({
    normalizeEntry: (raw) => (raw.startsWith("id:") ? raw.slice(3) : null),
    authentication: "verified",
    aliases: [
      {
        key: "name",
        normalizeEntry: (raw) => (raw.startsWith("name:") ? raw.slice(5) : null),
        authentication: "mutable",
      },
      {
        key: "tag",
        normalizeEntry: (raw) => (raw.startsWith("tag:") ? raw.slice(4) : null),
        dangerous: true,
      },
      { key: "legacy", normalizeEntry: (raw) => (raw.startsWith("legacy:") ? raw.slice(7) : null) },
    ],
  });

  it.each([
    ["id:123", "verified"],
    ["name:Alice", "mutable"],
    ["tag:alice#0001", "mutable"],
    ["legacy:123", "asserted"],
    ["rejected", undefined],
    ["id:   ", undefined],
    ["*", undefined],
  ] as const)("classifies %s as %s", (raw, expected) => {
    expect(identityEntryAuthenticationClassifier(identity)(raw)).toBe(expected);
  });

  it.each(["verified", "asserted", "unverified", "mutable"] as const)(
    "resolves predicate strength %s on the raw entry",
    (authentication) => {
      const classify = identityEntryAuthenticationClassifier({
        primary: {
          normalizeEntry: (raw) => raw.trim().toLowerCase(),
          authentication: (raw) => (raw === " RAW " ? authentication : "mutable"),
          dangerous: true,
        },
      });
      expect(classify(" RAW ")).toBe(authentication);
    },
  );

  it.each([false, true])("takes the strongest accepting field (reverse=%s)", (reverse) => {
    const fields = [
      { key: "name", authentication: "mutable" as const },
      { key: "id", authentication: "verified" as const },
      { key: "legacy" },
    ];
    if (reverse) {
      fields.reverse();
    }
    const descriptor: ChannelIngressIdentityDescriptor = {
      primary: { authentication: "unverified" },
      aliases: fields,
      isWildcardEntry: (raw) => raw === "everyone",
    };
    const classify = identityEntryAuthenticationClassifier(descriptor);
    expect(classify("123")).toBe("verified");
    expect(classify("everyone")).toBeUndefined();
  });

  it.each([
    [true, "mutable"],
    [false, "asserted"],
  ] as const)("resolves the legacy dangerous predicate (%s)", (dangerous, expected) => {
    const classify = identityEntryAuthenticationClassifier({
      primary: {
        authentication: () => undefined,
        dangerous: (raw) => raw === " RAW " && dangerous,
      },
    });
    expect(classify(" RAW ")).toBe(expected);
  });

  it("accepts the raw stable-identity input used by channel runtimes", () => {
    const classify = identityEntryAuthenticationClassifier({
      normalize: (raw) => raw.trim(),
      authentication: "asserted",
      aliases: [{ key: "name", authentication: "mutable" }],
    });
    expect(classify("id")).toBe("asserted");
  });
});