From 145cffee9ededa9035976fece367f2665c3fd8d6 Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Thu, 12 Oct 2023 16:12:43 -0700 Subject: [PATCH] rename hpke configs to collector credential everywhere --- app/src/ApiClient.ts | 50 +- app/src/accounts/AccountSummary.tsx | 2 +- .../NextSteps/InlineCollectorCredentials.tsx | 21 +- app/src/accounts/NextSteps/index.tsx | 34 +- app/src/accounts/index.tsx | 3 +- .../CollectorCredentialForm.tsx} | 14 +- .../CollectorCredentialList.tsx} | 68 +- .../index.tsx | 18 +- app/src/router.tsx | 4 +- .../tasks/TaskDetail/TaskPropertyTable.tsx | 14 +- .../TaskForm/CollectorCredentialSelect.tsx | 54 ++ app/src/tasks/TaskForm/HelpText.tsx | 2 +- app/src/tasks/TaskForm/HpkeConfigSelect.tsx | 50 -- app/src/tasks/TaskForm/index.tsx | 6 +- app/src/tasks/index.tsx | 8 +- ...ke_configs.rs => collector_credentials.rs} | 34 +- cli/src/main.rs | 8 +- cli/src/tasks.rs | 6 +- ...ke_configs.rs => collector_credentials.rs} | 6 +- client/src/lib.rs | 37 +- client/src/task.rs | 4 +- client/tests/collector_credentials.rs | 66 ++ client/tests/hpke_configs.rs | 58 -- client/tests/tasks.rs | 4 +- documentation/openapi.yml | 32 +- migration/src/lib.rs | 2 + ...e_hpke_configs_to_collector_credentials.rs | 67 ++ src/clients/aggregator_client/api_types.rs | 2 +- src/entity.rs | 8 +- src/entity/account.rs | 10 +- ...hpke_config.rs => collector_credential.rs} | 47 +- src/entity/task.rs | 16 +- src/entity/task/new_task.rs | 31 +- src/entity/task/provisionable_task.rs | 6 +- src/routes.rs | 21 +- src/routes/collector_credentials.rs | 85 +++ src/routes/hpke_configs.rs | 69 -- test-support/src/fixtures.rs | 8 +- test-support/src/lib.rs | 4 +- tests/collector_credentials.rs | 686 ++++++++++++++++++ tests/hpke_configs.rs | 550 -------------- tests/tasks.rs | 34 +- 42 files changed, 1273 insertions(+), 976 deletions(-) rename app/src/{hpke-configs/HpkeConfigForm.tsx => collector-credentials/CollectorCredentialForm.tsx} (88%) rename app/src/{hpke-configs/HpkeConfigList.tsx => collector-credentials/CollectorCredentialList.tsx} (71%) rename app/src/{hpke-configs => collector-credentials}/index.tsx (74%) create mode 100644 app/src/tasks/TaskForm/CollectorCredentialSelect.tsx delete mode 100644 app/src/tasks/TaskForm/HpkeConfigSelect.tsx rename cli/src/{hpke_configs.rs => collector_credentials.rs} (80%) rename client/src/{hpke_configs.rs => collector_credentials.rs} (83%) create mode 100644 client/tests/collector_credentials.rs delete mode 100644 client/tests/hpke_configs.rs create mode 100644 migration/src/m20231012_225001_rename_hpke_configs_to_collector_credentials.rs rename src/entity/{hpke_config.rs => collector_credential.rs} (73%) create mode 100644 src/routes/collector_credentials.rs delete mode 100644 src/routes/hpke_configs.rs create mode 100644 tests/collector_credentials.rs delete mode 100644 tests/hpke_configs.rs diff --git a/app/src/ApiClient.ts b/app/src/ApiClient.ts index 8b931c99..cf77f317 100644 --- a/app/src/ApiClient.ts +++ b/app/src/ApiClient.ts @@ -74,7 +74,7 @@ export interface Task { max_batch_size: number | null; report_count: number; aggregate_collection_count: number; - hpke_config_id: string; + collector_credential_id: string; } export interface CollectorAuthToken { @@ -153,7 +153,7 @@ export interface ApiToken { last_used_at?: string; } -export interface HpkeConfig { +export interface CollectorCredential { id: string; contents: { id: number; @@ -436,35 +436,45 @@ export class ApiClient { return res.data as QueueJob; } - async deleteHpkeConfig(hpkeConfigId: string) { - await this.delete(`/api/hpke_configs/${hpkeConfigId}`); + async deleteCollectorCredential(collectorCredentialId: string) { + await this.delete(`/api/collector_credentials/${collectorCredentialId}`); return null; } - async updateHpkeConfig(hpkeConfigId: string, hpkeConfig: { name: string }) { - await this.patch(`/api/hpke_configs/${hpkeConfigId}`, hpkeConfig); + async updateCollectorCredential( + collectorCredentialId: string, + collectorCredential: { name: string }, + ) { + await this.patch( + `/api/collector_credentials/${collectorCredentialId}`, + collectorCredential, + ); return null; } - async hpkeConfig(hpkeConfigId: string): Promise { - const res = await this.get(`/api/hpke_configs/${hpkeConfigId}`); - return res.data as HpkeConfig; + async collectorCredential( + collectorCredentialId: string, + ): Promise { + const res = await this.get( + `/api/collector_credentials/${collectorCredentialId}`, + ); + return res.data as CollectorCredential; } - async createHpkeConfig( + async createCollectorCredential( accountId: string, - hpkeConfig: { contents: string; name: string }, + collectorCredential: { contents: string; name: string }, ): Promise< - | HpkeConfig + | CollectorCredential | { error: ValidationErrorsFor<{ contents: string; name: string }> } > { const res = await this.post( - `/api/accounts/${accountId}/hpke_configs`, - hpkeConfig, + `/api/accounts/${accountId}/collector_credentials`, + collectorCredential, ); switch (res.status) { case 201: - return res.data as HpkeConfig; + return res.data as CollectorCredential; case 400: return { error: res.data } as { error: ValidationErrorsFor<{ contents: string; name: string }>; @@ -474,9 +484,13 @@ export class ApiClient { } } - async accountHpkeConfigs(accountId: string): Promise { - const res = await this.get(`/api/accounts/${accountId}/hpke_configs`); - return res.data as HpkeConfig[]; + async accountCollectorCredentials( + accountId: string, + ): Promise { + const res = await this.get( + `/api/accounts/${accountId}/collector_credentials`, + ); + return res.data as CollectorCredential[]; } } diff --git a/app/src/accounts/AccountSummary.tsx b/app/src/accounts/AccountSummary.tsx index 5c16d939..e9f0a18d 100644 --- a/app/src/accounts/AccountSummary.tsx +++ b/app/src/accounts/AccountSummary.tsx @@ -170,7 +170,7 @@ export default function AccountSummary() { - + HPKE Configs diff --git a/app/src/accounts/NextSteps/InlineCollectorCredentials.tsx b/app/src/accounts/NextSteps/InlineCollectorCredentials.tsx index ea752f0a..38c04d13 100644 --- a/app/src/accounts/NextSteps/InlineCollectorCredentials.tsx +++ b/app/src/accounts/NextSteps/InlineCollectorCredentials.tsx @@ -57,24 +57,27 @@ function SaveApiToken({ onToken }: { onToken: (token: string) => void }) { export default function InlineCollectorCredentials() { const apiClient = React.useContext(ApiClientContext); const { accountId } = useParams() as { accountId: string }; - const [anyHpkeConfigs, setAnyHpkeConfigs] = React.useState(false); + const [anyCollectorCredentials, setAnyCollectorCredentials] = + React.useState(false); const [inFlight, setInFlight] = React.useState(false); useInterval( React.useCallback(() => { - if (inFlight || anyHpkeConfigs) return; + if (inFlight || anyCollectorCredentials) return; setInFlight(true); - apiClient.accountHpkeConfigs(accountId).then((hpkeConfigs) => { - setAnyHpkeConfigs(hpkeConfigs.length > 0); - setInFlight(false); - }); - }, [apiClient, setInFlight, setAnyHpkeConfigs]), + apiClient + .accountCollectorCredentials(accountId) + .then((collectorCredentials) => { + setAnyCollectorCredentials(collectorCredentials.length > 0); + setInFlight(false); + }); + }, [apiClient, setInFlight, setAnyCollectorCredentials]), 1000, ); const [token, setToken] = React.useState("«TOKEN»"); const { revalidate, state } = useRevalidator(); - if (anyHpkeConfigs) { + if (anyCollectorCredentials) { return ( <>

Success

@@ -84,7 +87,7 @@ export default function InlineCollectorCredentials() { ); } else { - const command = `divviup -t ${token} hpke-config generate`; + const command = `divviup -t ${token} collector-credential generate`; return ( <>
    diff --git a/app/src/accounts/NextSteps/index.tsx b/app/src/accounts/NextSteps/index.tsx index 48d55661..958daf11 100644 --- a/app/src/accounts/NextSteps/index.tsx +++ b/app/src/accounts/NextSteps/index.tsx @@ -1,7 +1,12 @@ import { Steps } from "primereact/steps"; import { Button, Card, Col, Row } from "react-bootstrap"; import { useLoaderData } from "react-router-dom"; -import { Account, Aggregator, HpkeConfig, Task } from "../../ApiClient"; +import { + Account, + Aggregator, + CollectorCredential, + Task, +} from "../../ApiClient"; import { LinkContainer } from "react-router-bootstrap"; import AggregatorTypeSelection from "./AggregatorTypeSelection"; import InlineCollectorCredentials from "./InlineCollectorCredentials"; @@ -17,20 +22,20 @@ const STEPS = [ function determineModel({ account, - hpkeConfigs, + collectorCredentials, aggregators, }: { account: Account; - hpkeConfigs: HpkeConfig[]; + collectorCredentials: CollectorCredential[]; aggregators: Aggregator[]; }): number { const aggregatorStepComplete = account.intends_to_use_shared_aggregators === true || !!aggregators.find((a) => !!a.account_id); - const hpkeConfigStepComplete = hpkeConfigs.length > 0; + const collectorCredentialStepComplete = collectorCredentials.length > 0; const nextStepIndex = - [aggregatorStepComplete, hpkeConfigStepComplete, false].findIndex( + [aggregatorStepComplete, collectorCredentialStepComplete, false].findIndex( (x) => !x, ) + 1; @@ -50,18 +55,19 @@ function NextInner({ activeIndex }: { activeIndex: number | undefined }) { } export default function NextSteps() { - const { account, hpkeConfigs, aggregators, tasks } = useLoaderData() as { - account: Promise; - hpkeConfigs: Promise; - aggregators: Promise; - tasks: Promise; - }; + const { account, collectorCredentials, aggregators, tasks } = + useLoaderData() as { + account: Promise; + collectorCredentials: Promise; + aggregators: Promise; + tasks: Promise; + }; const loadedTasks = usePromise(tasks, []); const activeIndex = usePromiseAll( - [account, hpkeConfigs, aggregators], - ([account, hpkeConfigs, aggregators]) => - determineModel({ account, hpkeConfigs, aggregators }), + [account, collectorCredentials, aggregators], + ([account, collectorCredentials, aggregators]) => + determineModel({ account, collectorCredentials, aggregators }), 1, ); diff --git a/app/src/accounts/index.tsx b/app/src/accounts/index.tsx index 799e7b26..c80cefab 100644 --- a/app/src/accounts/index.tsx +++ b/app/src/accounts/index.tsx @@ -81,7 +81,8 @@ export default function accounts( return defer({ apiTokens: apiClient.accountApiTokens(accountId), tasks: apiClient.accountTasks(accountId), - hpkeConfigs: apiClient.accountHpkeConfigs(accountId), + collectorCredentials: + apiClient.accountCollectorCredentials(accountId), aggregators: apiClient.accountAggregators(accountId), account: apiClient.account(accountId), }); diff --git a/app/src/hpke-configs/HpkeConfigForm.tsx b/app/src/collector-credentials/CollectorCredentialForm.tsx similarity index 88% rename from app/src/hpke-configs/HpkeConfigForm.tsx rename to app/src/collector-credentials/CollectorCredentialForm.tsx index 5a24e45a..cba1adeb 100644 --- a/app/src/hpke-configs/HpkeConfigForm.tsx +++ b/app/src/collector-credentials/CollectorCredentialForm.tsx @@ -16,19 +16,19 @@ import { KeyFill } from "react-bootstrap-icons"; import { useFetcher } from "react-router-dom"; import { formikErrors } from "../ApiClient"; -export default function HpkeConfigForm() { +export default function CollectorCredentialForm() { const fetcher = useFetcher(); const [name, setName] = React.useState(""); - const [hpke, setHpke] = React.useState(""); + const [collectorCredential, setCollectorCredential] = React.useState(""); const reader = React.useMemo(() => { const reader = new FileReader(); reader.addEventListener("load", () => { if (typeof reader.result === "string") { - setHpke(reader.result.split(",")[1]); + setCollectorCredential(reader.result.split(",")[1]); } }); return reader; - }, [setHpke]); + }, [setCollectorCredential]); const onChange: ChangeEventHandler = React.useCallback( (event) => { const files = event.target.files; @@ -44,12 +44,12 @@ export default function HpkeConfigForm() { useEffect(() => { if (typeof fetcher.data === "object" && !("error" in fetcher.data)) { setName(""); - setHpke(""); + setCollectorCredential(""); if (ref.current) { ref.current.value = ""; } } - }, [fetcher, setName, setHpke, ref]); + }, [fetcher, setName, setCollectorCredential, ref]); const errors = formikErrors<{ contents?: string; name?: string }>( fetcher.data && "error" in fetcher.data @@ -97,7 +97,7 @@ export default function HpkeConfigForm() { ) : null} - + diff --git a/app/src/hpke-configs/HpkeConfigList.tsx b/app/src/collector-credentials/CollectorCredentialList.tsx similarity index 71% rename from app/src/hpke-configs/HpkeConfigList.tsx rename to app/src/collector-credentials/CollectorCredentialList.tsx index 45be9f47..34d9a7b1 100644 --- a/app/src/hpke-configs/HpkeConfigList.tsx +++ b/app/src/collector-credentials/CollectorCredentialList.tsx @@ -11,7 +11,7 @@ import { useLoaderData, useNavigation, } from "react-router-dom"; -import { HpkeConfig } from "../ApiClient"; +import { CollectorCredential } from "../ApiClient"; import Table from "react-bootstrap/Table"; import React from "react"; import { DateTime } from "luxon"; @@ -20,9 +20,9 @@ import FormGroup from "react-bootstrap/FormGroup"; import InputGroup from "react-bootstrap/InputGroup"; import Modal from "react-bootstrap/Modal"; import Placeholder from "react-bootstrap/Placeholder"; -import HpkeConfigForm from "./HpkeConfigForm"; +import CollectorCredentialForm from "./CollectorCredentialForm"; -export default function HpkeConfigs() { +export default function CollectorCredentials() { return ( <> @@ -39,12 +39,12 @@ export default function HpkeConfigs() { - + - + @@ -59,9 +59,9 @@ function Breadcrumbs() { ); } -function HpkeConfigList() { - const { hpkeConfigs } = useLoaderData() as { - hpkeConfigs: Promise; +function CollectorCredentialList() { + const { collectorCredentials } = useLoaderData() as { + collectorCredentials: Promise; }; return ( @@ -78,10 +78,13 @@ function HpkeConfigList() { - - {(hpkeConfigs: HpkeConfig[]) => - hpkeConfigs.map((hpkeConfig) => ( - + + {(collectorCredentials: CollectorCredential[]) => + collectorCredentials.map((collectorCredential) => ( + )) } @@ -91,7 +94,11 @@ function HpkeConfigList() { ); } -function Name({ hpkeConfig }: { hpkeConfig: HpkeConfig }) { +function Name({ + collectorCredential, +}: { + collectorCredential: CollectorCredential; +}) { const [isEditing, setEditing] = useState(false); const edit = useCallback(() => setEditing(true), [setEditing]); const fetcher = useFetcher(); @@ -100,13 +107,13 @@ function Name({ hpkeConfig }: { hpkeConfig: HpkeConfig }) { }, [fetcher, setEditing]); if (isEditing) { return ( - + @@ -120,7 +127,8 @@ function Name({ hpkeConfig }: { hpkeConfig: HpkeConfig }) { } else { return ( - {hpkeConfig.name || `HPKE Config ${hpkeConfig.contents.id}`}{" "} + {collectorCredential.name || + `HPKE Config ${collectorCredential.contents.id}`}{" "} - +