Skip to content

Commit

Permalink
Merge pull request #200 from stephb9959/main
Browse files Browse the repository at this point in the history
[WIFI-13534] Captive portal configuration schema fixes
  • Loading branch information
BourqueCharles authored Mar 21, 2024
2 parents 6c812cd + 65f4832 commit 6f56df5
Show file tree
Hide file tree
Showing 11 changed files with 340 additions and 166 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wlan-cloud-owprov-ui",
"version": "3.0.2(1)",
"version": "3.0.2(2)",
"description": "",
"main": "index.tsx",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useCreateResource, useUpdateResource } from 'hooks/Network/Resources';
import { Note } from 'models/Note';
import { Resource } from 'models/Resource';
import { INTERFACE_CAPTIVE_SCHEMA } from 'pages/ConfigurationPage/ConfigurationCard/ConfigurationSectionsCard/InterfaceSection/interfacesConstants';
import Captive from 'pages/ConfigurationPage/ConfigurationCard/ConfigurationSectionsCard/InterfaceSection/SingleInterface/Captive/Captive';
import Captive from 'pages/ConfigurationPage/ConfigurationCard/ConfigurationSectionsCard/InterfaceSection/SingleInterface/SsidList/Captive/Captive';

export const EDIT_SCHEMA = (t: (str: string) => string) =>
object().shape({
Expand Down Expand Up @@ -211,7 +211,7 @@ const InterfaceCaptiveResource = ({
<StringField name="_unused_name" label={t('common.name')} isRequired isDisabled={isDisabled} />
<StringField name="_unused_description" label={t('common.description')} isDisabled={isDisabled} />
</SimpleGrid>
<Captive namePrefix="editing" isDisabled={isDisabled} isActive />
<Captive namePrefix="editing" isDisabled={isDisabled} />
</TabPanel>
<TabPanel>
<NotesTable name="_unused_notes" isDisabled={isDisabled} />
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Flex, Heading, SimpleGrid } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { INTERFACE_SSID_MULTIPSK_SCHEMA, NO_MULTI_PROTOS } from '../../interfacesConstants';
import AccessControlList from './AccessControlList';
import Captive from './Captive';
import RateLimit from './RateLimit';
import Roaming from './Roaming';
import Rrm from './Rrm';
Expand Down Expand Up @@ -187,6 +188,7 @@ const AdvancedSettings: React.FC<{ editing: boolean; namePrefix: string }> = ({
</SimpleGrid>
<RateLimit editing={editing} namePrefix={`${namePrefix}.rate-limit`} />
<Rrm editing={editing} namePrefix={`${namePrefix}.rrm`} />
<Captive editing={editing} namePrefix={`${namePrefix}.captive`} />
<AccessControlList editing={editing} namePrefix={`${namePrefix}.access-control-list`} />
<Roaming editing={editing} namePrefix={`${namePrefix}.roaming`} />
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import React from 'react';
import { Heading, Select, SimpleGrid, Text } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { object, string } from 'yup';
import CreatableSelectField from 'components/FormFields/CreatableSelectField';
import FileInputFieldModal from 'components/FormFields/FileInputFieldModal';
import NumberField from 'components/FormFields/NumberField';
import ObjectArrayFieldModal from 'components/FormFields/ObjectArrayFieldModal';
import SelectField from 'components/FormFields/SelectField';
import StringField from 'components/FormFields/StringField';

const CREDENTIALS_SCHEMA = (t: (str: string) => string, useDefault = false) => {
const shape = object().shape({
username: string().required(t('form.required')).default(''),
password: string().required(t('form.required')).default(''),
});

return useDefault ? shape : shape.nullable().default(undefined);
};

interface Props {
isDisabled?: boolean;
namePrefix: string;
onAuthModeChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
authMode?: string;
}

const CaptiveForm = ({ isDisabled, namePrefix, onAuthModeChange, authMode }: Props) => {
const fieldProps = (suffix: string) => ({
name: `${namePrefix}.${suffix}`,
label: suffix,
definitionKey: `interface.ssid.pass-point.${suffix}`,
isDisabled,
});
const { t } = useTranslation();

const credFields = React.useMemo(
() => (
<SimpleGrid minChildWidth="300px" gap={4}>
<StringField name="username" label="username" isRequired />
<StringField name="password" label="password" isRequired />
</SimpleGrid>
),
[],
);
const credCols = React.useMemo(
() => [
{
id: 'username',
Header: 'username',
Footer: '',
accessor: 'username',
},
{
id: 'password',
Header: 'password',
Footer: '',
accessor: 'password',
},
],
[],
);

return (
<>
<Heading size="md" display="flex" alignItems="center" mt={2}>
<Text pt={1}>Captive Portal</Text>
<Select w="max-content" ml={2} value={authMode} onChange={onAuthModeChange} isDisabled={isDisabled}>
<option value="none">None</option>
<option value="click">Click</option>
<option value="radius">Radius</option>
<option value="credentials">Credentials</option>
<option value="uam">UAM</option>
</Select>
</Heading>
{authMode !== undefined && (
<SimpleGrid minChildWidth="300px" spacing="20px" mb={8} mt={2} w="100%">
<CreatableSelectField
{...fieldProps('walled-garden-fqdn')}
placeholder="Example: *.google.com"
emptyIsUndefined={authMode !== 'uam'}
isRequired={authMode === 'uam'}
/>
<CreatableSelectField
{...fieldProps('walled-garden-ipaddr')}
placeholder="Example: 192.168.0.1"
emptyIsUndefined
/>
<FileInputFieldModal
{...fieldProps('web-root')}
fileName="configuration.captive.web-root-filename"
definitionKey="service.captive.web-root"
explanation={t('form.captive_web_root_explanation')}
test={() => true}
acceptedFileTypes=".tar"
isDisabled={isDisabled}
canDelete
isRequired
wantBase64
/>
<NumberField {...fieldProps('idle-timeout')} isRequired w="100px" />
<NumberField {...fieldProps('session-timeout')} emptyIsUndefined acceptEmptyValue w="100px" />
{authMode === 'credentials' && (
<ObjectArrayFieldModal
{...fieldProps('credentials')}
fields={credFields}
columns={credCols}
schema={CREDENTIALS_SCHEMA}
isDisabled={isDisabled}
isRequired
/>
)}
{authMode === 'uam' && (
<>
<StringField {...fieldProps('uam-server')} isRequired />
<StringField {...fieldProps('uam-secret')} isRequired hideButton />
<NumberField {...fieldProps('uam-port')} isRequired />
<StringField {...fieldProps('nasid')} isRequired />
<StringField {...fieldProps('nasmac')} emptyIsUndefined />
<SelectField
{...fieldProps('mac-format')}
options={[
{ value: 'aabbccddeeff', label: 'aabbccddeeff' },
{ value: 'aa-bb-cc-dd-ee-ff', label: 'aa-bb-cc-dd-ee-ff' },
{ value: 'aa:bb:cc:dd:ee:ff', label: 'aa:bb:cc:dd:ee:ff' },
{ value: 'AABBCCDDEEFF', label: 'AABBCCDDEEFF' },
{ value: 'AA:BB:CC:DD:EE:FF', label: 'AA:BB:CC:DD:EE:FF' },
{ value: 'AA-BB-CC-DD-EE-FF', label: 'AA-BB-CC-DD-EE-FF' },
]}
isRequired
/>
<StringField {...fieldProps('ssid')} emptyIsUndefined />
</>
)}
{(authMode === 'radius' || authMode === 'uam') && (
<>
<StringField {...fieldProps('auth-server')} isRequired />
<StringField {...fieldProps('auth-secret')} isRequired hideButton />
<NumberField {...fieldProps('auth-port')} isRequired />
<StringField {...fieldProps('acct-server')} emptyIsUndefined />
<StringField {...fieldProps('acct-secret')} emptyIsUndefined hideButton />
<NumberField {...fieldProps('acct-port')} emptyIsUndefined acceptEmptyValue />
<NumberField {...fieldProps('acct-interval')} emptyIsUndefined acceptEmptyValue />
</>
)}
</SimpleGrid>
)}
</>
);
};

export default React.memo(CaptiveForm);
Loading

0 comments on commit 6f56df5

Please sign in to comment.