Skip to content

Commit 75c184f

Browse files
Merge pull request #254 from CodeForPhilly/secure-eligibilitycheck-endpoints
chore: Updated security and organization of endpoints in EligibilityCheckResource.java
2 parents 33518ed + 554e95f commit 75c184f

File tree

11 files changed

+247
-181
lines changed

11 files changed

+247
-181
lines changed

builder-api/src/main/java/org/acme/controller/EligibilityCheckResource.java

Lines changed: 151 additions & 133 deletions
Large diffs are not rendered by default.

builder-api/src/main/java/org/acme/model/domain/EligibilityCheck.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ public class EligibilityCheck {
2020
private String evaluationUrl;
2121
private Boolean isArchived;
2222

23+
public EligibilityCheck() {
24+
}
25+
26+
public EligibilityCheck(
27+
String name,
28+
String module,
29+
String description,
30+
List<ParameterDefinition> parameterDefinitions,
31+
String ownerId
32+
) {
33+
this.name = name;
34+
this.module = module;
35+
this.description = description;
36+
this.parameterDefinitions = parameterDefinitions;
37+
this.ownerId = ownerId;
38+
this.version = "1.0.0";
39+
}
40+
2341
public String getId() {
2442
return this.id;
2543
}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.acme.model.dto;
22

33
public class CheckDmnRequest {
4-
public String id;
54
public String dmnModel;
65
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.acme.model.dto;
2+
3+
import org.acme.model.domain.ParameterDefinition;
4+
import java.util.List;
5+
6+
public class CreateCheckRequest {
7+
public String name;
8+
public String module;
9+
public String description;
10+
public List<ParameterDefinition> parameterDefinitions;
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.acme.model.dto;
2+
3+
import org.acme.model.domain.ParameterDefinition;
4+
import java.util.List;
5+
6+
public class UpdateCheckRequest {
7+
public String description;
8+
public List<ParameterDefinition> parameterDefinitions;
9+
}

builder-api/src/main/resources/application.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
quarkus.http.cors.enabled=true
22
quarkus.http.cors.origins=*
3-
quarkus.http.cors.methods=GET,POST,PUT,DELETE
3+
quarkus.http.cors.methods=GET,POST,PUT,PATCH,DELETE
44
quarkus.http.cors.headers=Authorization,Content-Type
55

66
quarkus.datasource.db-kind=sqlite

builder-frontend/src/api/check.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { authFetch } from "@/api/auth";
22

3-
import type { EligibilityCheck, OptionalBoolean } from "@/types";
3+
import type { EligibilityCheck, OptionalBoolean, CreateCheckRequest, UpdateCheckRequest } from "@/types";
44

55
const apiUrl = import.meta.env.VITE_API_URL;
66

@@ -54,7 +54,7 @@ export const fetchCheck = async (
5454
}
5555
};
5656

57-
export const addCheck = async (check: EligibilityCheck) => {
57+
export const addCheck = async (check: CreateCheckRequest): Promise<EligibilityCheck> => {
5858
const url = apiUrl + "/custom-checks";
5959
try {
6060
const response = await authFetch(url, {
@@ -63,7 +63,12 @@ export const addCheck = async (check: EligibilityCheck) => {
6363
"Content-Type": "application/json",
6464
Accept: "application/json",
6565
},
66-
body: JSON.stringify(check),
66+
body: JSON.stringify({
67+
name: check.name,
68+
module: check.module,
69+
description: check.description,
70+
parameterDefinitions: check.parameterDefinitions,
71+
}),
6772
});
6873

6974
if (!response.ok) {
@@ -77,16 +82,21 @@ export const addCheck = async (check: EligibilityCheck) => {
7782
}
7883
};
7984

80-
export const updateCheck = async (check: EligibilityCheck) => {
81-
const url = apiUrl + "/custom-checks";
85+
export const updateCheck = async (checkId: string, updates: UpdateCheckRequest): Promise<EligibilityCheck> => {
86+
const url = apiUrl + `/custom-checks/${checkId}`;
8287
try {
88+
// Build request body with only non-undefined fields (partial update)
89+
const body: UpdateCheckRequest = {};
90+
if (updates.description !== undefined) body.description = updates.description;
91+
if (updates.parameterDefinitions !== undefined) body.parameterDefinitions = updates.parameterDefinitions;
92+
8393
const response = await authFetch(url, {
84-
method: "PUT",
94+
method: "PATCH",
8595
headers: {
8696
"Content-Type": "application/json",
8797
Accept: "application/json",
8898
},
89-
body: JSON.stringify(check),
99+
body: JSON.stringify(body),
90100
});
91101

92102
if (!response.ok) {
@@ -101,15 +111,15 @@ export const updateCheck = async (check: EligibilityCheck) => {
101111
};
102112

103113
export const saveCheckDmn = async (checkId: string, dmnModel: string) => {
104-
const url = apiUrl + "/save-check-dmn";
114+
const url = apiUrl + `/custom-checks/${checkId}/dmn`;
105115
try {
106116
const response = await authFetch(url, {
107-
method: "POST",
117+
method: "PUT",
108118
headers: {
109119
"Content-Type": "application/json",
110120
Accept: "application/json",
111121
},
112-
body: JSON.stringify({ id: checkId, dmnModel: dmnModel }),
122+
body: JSON.stringify({ dmnModel: dmnModel }),
113123
});
114124

115125
if (!response.ok) {
@@ -125,15 +135,15 @@ export const validateCheckDmn = async (
125135
checkId: string,
126136
dmnModel: string
127137
): Promise<string[]> => {
128-
const url = apiUrl + "/validate-check-dmn";
138+
const url = apiUrl + `/custom-checks/${checkId}/dmn/validate`;
129139
try {
130140
const response = await authFetch(url, {
131141
method: "POST",
132142
headers: {
133143
"Content-Type": "application/json",
134144
Accept: "application/json",
135145
},
136-
body: JSON.stringify({ id: checkId, dmnModel: dmnModel }),
146+
body: JSON.stringify({ dmnModel: dmnModel }),
137147
});
138148

139149
if (!response.ok) {
@@ -143,7 +153,7 @@ export const validateCheckDmn = async (
143153
const data = await response.json();
144154
return data.errors;
145155
} catch (error) {
146-
console.error("Error validation DMN for check:", error);
156+
console.error("Error validating DMN for check:", error);
147157
throw error; // rethrow so you can handle it in your component if needed
148158
}
149159
};
@@ -203,7 +213,7 @@ export const evaluateWorkingCheck = async (
203213
export const getRelatedPublishedChecks = async (
204214
checkId: string
205215
): Promise<EligibilityCheck[]> => {
206-
const url = apiUrl + `/custom-checks/${checkId}/published-check-versions`;
216+
const url = apiUrl + `/custom-checks/${checkId}/versions`;
207217
try {
208218
const response = await authFetch(url, {
209219
method: "GET",
@@ -226,7 +236,7 @@ export const getRelatedPublishedChecks = async (
226236
export const publishCheck = async (
227237
checkId: string
228238
): Promise<OptionalBoolean> => {
229-
const url = apiUrl + `/publish-check/${checkId}`;
239+
const url = apiUrl + `/custom-checks/${checkId}/publish`;
230240
try {
231241
const response = await authFetch(url, {
232242
method: "POST",

builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/eligibilityCheckDetailResource.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,15 @@ const eligibilityCheckDetailResource = (
6868
});
6969

7070
const addParameter = async (parameterDef: ParameterDefinition) => {
71-
const updatedCheck: EligibilityCheckDetail = {
72-
...eligibilityCheck,
73-
parameterDefinitions: [
74-
...(eligibilityCheck.parameterDefinitions || []),
75-
parameterDef,
76-
],
77-
};
71+
const updatedParameterDefinitions = [
72+
...(eligibilityCheck.parameterDefinitions || []),
73+
parameterDef,
74+
];
7875
setActionInProgress(true);
7976
try {
80-
await updateCheck(updatedCheck);
77+
await updateCheck(eligibilityCheck.id, {
78+
parameterDefinitions: updatedParameterDefinitions,
79+
});
8180
await refetch();
8281
} catch (e) {
8382
console.error("Failed to add parameter", e);
@@ -92,14 +91,12 @@ const eligibilityCheckDetailResource = (
9291
const updatedParameters = [...eligibilityCheck.parameterDefinitions];
9392
updatedParameters[parameterIndex] = parameterDef;
9493
console.log("updatedParameters", updatedParameters);
95-
const updatedCheck: EligibilityCheckDetail = {
96-
...eligibilityCheck,
97-
parameterDefinitions: updatedParameters,
98-
};
9994

10095
setActionInProgress(true);
10196
try {
102-
await updateCheck(updatedCheck);
97+
await updateCheck(eligibilityCheck.id, {
98+
parameterDefinitions: updatedParameters,
99+
});
103100
await refetch();
104101
} catch (e) {
105102
console.error("Failed to update parameter", e);
@@ -110,14 +107,12 @@ const eligibilityCheckDetailResource = (
110107
const removeParameter = async (parameterIndex: number) => {
111108
const updatedParameters = [...eligibilityCheck.parameterDefinitions];
112109
updatedParameters.splice(parameterIndex, 1);
113-
const updatedCheck: EligibilityCheckDetail = {
114-
...eligibilityCheck,
115-
parameterDefinitions: updatedParameters,
116-
};
117110

118111
setActionInProgress(true);
119112
try {
120-
await updateCheck(updatedCheck);
113+
await updateCheck(eligibilityCheck.id, {
114+
parameterDefinitions: updatedParameters,
115+
});
121116
await refetch();
122117
} catch (e) {
123118
console.error("Failed to remove parameter", e);

builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckResource.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { createResource, createEffect, Accessor, createSignal } from "solid-js";
22
import { createStore } from "solid-js/store";
33

4-
import type { EligibilityCheck } from "@/types";
4+
import type { EligibilityCheck, CreateCheckRequest } from "@/types";
55
import { addCheck, archiveCheck, fetchUserDefinedChecks } from "@/api/check";
66

77
export interface EligibilityCheckResource {
88
checks: () => EligibilityCheck[];
99
actions: {
10-
addNewCheck: (check: EligibilityCheck) => Promise<void>;
10+
addNewCheck: (check: CreateCheckRequest) => Promise<void>;
1111
removeCheck: (checkIdToRemove: string) => Promise<void>;
1212
};
1313
actionInProgress: Accessor<boolean>;
@@ -32,7 +32,7 @@ const eligibilityCheckResource = (): EligibilityCheckResource => {
3232
});
3333

3434
// Actions
35-
const addNewCheck = async (check: EligibilityCheck) => {
35+
const addNewCheck = async (check: CreateCheckRequest) => {
3636
setActionInProgress(true);
3737
try {
3838
await addCheck(check);

builder-frontend/src/components/homeScreen/eligibilityCheckList/modals/CheckModal.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createStore } from "solid-js/store";
22

3-
import type { EligibilityCheck } from "@/types";
3+
import type { CreateCheckRequest } from "@/types";
44

55
type CheckValues = {
66
name: string;
@@ -11,7 +11,7 @@ const EditCheckModal = ({
1111
modalAction,
1212
closeModal,
1313
}: {
14-
modalAction: (check: EligibilityCheck) => Promise<void>;
14+
modalAction: (check: CreateCheckRequest) => Promise<void>;
1515
closeModal: () => void;
1616
}) => {
1717
const [newCheck, setNewCheck] = createStore<CheckValues>({
@@ -84,17 +84,10 @@ const EditCheckModal = ({
8484
console.log("Please fill in all fields.");
8585
return;
8686
}
87-
const check: EligibilityCheck = {
88-
id:
89-
newCheck.module.toLowerCase() +
90-
"-" +
91-
newCheck.name.toLowerCase().replace(/\s+/g, "_"),
87+
const check: CreateCheckRequest = {
9288
name: newCheck.name,
93-
version: "1.0.0",
94-
9589
module: newCheck.module,
9690
description: newCheck.description,
97-
inputDefinition: {},
9891
parameterDefinitions: [],
9992
};
10093
await modalAction(check);

0 commit comments

Comments
 (0)