- ${msg(
- "When enabled, code-based multi-factor authentication can be used by appending a semicolon and the TOTP code to the password. This should only be enabled if all users that will bind to this provider have a TOTP device configured, as otherwise a password may incorrectly be rejected if it contains a semicolon.",
- )}
-
-
-
-
- ${msg("Protocol settings")}
-
-
-
-
-
-
-
- ${msg(`List of CIDRs (comma-seperated) that clients can connect from. A more specific
- CIDR will match before a looser one. Clients connecting from a non-specified CIDR
- will be dropped.`)}
-
-
-
-
-
-
-
-
- ${msg("Advanced flow settings")}
-
-
-
-
- ${msg("Flow used when logging out of this provider.")}
-
-
-
- `;
+ renderForm() {
+ return renderForm(this.instance ?? {}, [], this.brand);
}
}
diff --git a/web/src/admin/providers/radius/RadiusProviderFormForm.ts b/web/src/admin/providers/radius/RadiusProviderFormForm.ts
new file mode 100644
index 0000000000..a88be56afe
--- /dev/null
+++ b/web/src/admin/providers/radius/RadiusProviderFormForm.ts
@@ -0,0 +1,161 @@
+import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
+import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
+import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
+import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
+import { DualSelectPair } from "@goauthentik/elements/ak-dual-select/types";
+import "@goauthentik/elements/forms/FormGroup";
+import "@goauthentik/elements/forms/HorizontalFormElement";
+import "@goauthentik/elements/forms/SearchSelect";
+
+import { msg } from "@lit/localize";
+import { html } from "lit";
+import { ifDefined } from "lit/directives/if-defined.js";
+
+import {
+ FlowsInstancesListDesignationEnum,
+ PropertymappingsApi,
+ RadiusProviderPropertyMapping,
+ ValidationError,
+} from "@goauthentik/api";
+
+export async function radiusPropertyMappingsProvider(page = 1, search = "") {
+ const propertyMappings = await new PropertymappingsApi(
+ DEFAULT_CONFIG,
+ ).propertymappingsProviderRadiusList({
+ ordering: "name",
+ pageSize: 20,
+ search: search.trim(),
+ page,
+ });
+ return {
+ pagination: propertyMappings.pagination,
+ options: propertyMappings.results.map((m) => [m.pk, m.name, m.name, m]),
+ };
+}
+
+export function makeRadiusPropertyMappingsSelector(instanceMappings?: string[]) {
+ const localMappings = instanceMappings ? new Set(instanceMappings) : undefined;
+ return localMappings
+ ? ([pk, _]: DualSelectPair) => localMappings.has(pk)
+ : ([_0, _1, _2, _]: DualSelectPair) => [];
+}
+
+const mfaHelp = msg(
+ "When enabled, code-based multi-factor authentication can be used by appending a semicolon and the TOTP code to the password. This should only be enabled if all users that will bind to this provider have a TOTP device configured, as otherwise a password may incorrectly be rejected if it contains a semicolon.",
+);
+
+const clientNetworksHelp = msg(
+ "List of CIDRs (comma-seperated) that clients can connect from. A more specific CIDR will match before a looser one. Clients connecting from a non-specified CIDR will be dropped.",
+);
+
+// All Provider objects have an Authorization flow, but not all providers have an Authentication
+// flow. Radius needs only one field, but it is not the Authorization field, it is an
+// Authentication field. So, yeah, we're using the authorization field to store the
+// authentication information, which is why the ak-branded-flow-search call down there looks so
+// weird-- we're looking up Authentication flows, but we're storing them in the Authorization
+// field of the target Provider.
+
+export function renderForm(
+ provider?: Partial,
+ errors: ValidationError = {},
+ brand?: CurrentBrand,
+) {
+ return html`
+
+
+
+
+
+
${msg("Flow used for users to authenticate.")}
+
+
+
+
+
${mfaHelp}
+
+
+
+ ${msg("Protocol settings")}
+
+
+
+
+
+
+
+
+
+ ${msg("Advanced flow settings")}
+
+
+
+
+ ${msg("Flow used when logging out of this provider.")}
+