fix(personal): reject ambiguous org identities
This commit is contained in:
+5
-2
@@ -79,12 +79,15 @@ public class OrgSnapshotEnterpriseKnowledgeAccessPolicy implements EnterpriseKno
|
|||||||
AND position_name IS NOT NULL
|
AND position_name IS NOT NULL
|
||||||
AND position_name <> ''
|
AND position_name <> ''
|
||||||
ORDER BY snapshot_date DESC, id ASC
|
ORDER BY snapshot_date DESC, id ASC
|
||||||
LIMIT 1
|
LIMIT 2
|
||||||
""", (rs, rowNum) -> new OrganizationIdentity(
|
""", (rs, rowNum) -> new OrganizationIdentity(
|
||||||
trimmed(rs.getString("project_code")),
|
trimmed(rs.getString("project_code")),
|
||||||
trimmed(rs.getString("position_name")),
|
trimmed(rs.getString("position_name")),
|
||||||
trimmed(rs.getString("position_level"))), tenantId, phone);
|
trimmed(rs.getString("position_level"))), tenantId, phone);
|
||||||
return rows.stream().filter(OrganizationIdentity::valid).findFirst();
|
if (rows.size() != 1 || !rows.get(0).valid()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(rows.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Long> authorizedFragmentIds(String tenantId, OrganizationIdentity identity) {
|
private List<Long> authorizedFragmentIds(String tenantId, OrganizationIdentity identity) {
|
||||||
|
|||||||
+18
@@ -90,6 +90,20 @@ class OrgSnapshotEnterpriseKnowledgeAccessPolicyTest {
|
|||||||
assertTrue(jdbc.sql.stream().anyMatch(value -> value.contains("employment_status = 'active'")));
|
assertTrue(jdbc.sql.stream().anyMatch(value -> value.contains("employment_status = 'active'")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void duplicateActivePhoneIdentitiesFailClosedBeforeAclLookup() {
|
||||||
|
RecordingJdbcTemplate jdbc = fixture();
|
||||||
|
jdbc.organizations = List.of(
|
||||||
|
Map.of("project_code", "PRJ-FCW", "position_name", "物业管家", "position_level", "一线"),
|
||||||
|
Map.of("project_code", "PRJ-YSF", "position_name", "物业管家", "position_level", "一线")
|
||||||
|
);
|
||||||
|
jdbc.fragmentIds = List.of(100101L);
|
||||||
|
|
||||||
|
assertTrue(new OrgSnapshotEnterpriseKnowledgeAccessPolicy(jdbc)
|
||||||
|
.authorize(new PersonalOwner("000000", 103L, null)).isEmpty());
|
||||||
|
assertFalse(jdbc.sql.stream().anyMatch(value -> value.contains("FROM aihr_knowledge_acl")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void aclQueryEnforcesTenantProjectPositionAndTenantScopes() {
|
void aclQueryEnforcesTenantProjectPositionAndTenantScopes() {
|
||||||
RecordingJdbcTemplate jdbc = fixture();
|
RecordingJdbcTemplate jdbc = fixture();
|
||||||
@@ -190,6 +204,7 @@ class OrgSnapshotEnterpriseKnowledgeAccessPolicyTest {
|
|||||||
private String phone;
|
private String phone;
|
||||||
private String expectedTenant;
|
private String expectedTenant;
|
||||||
private Map<String, String> organization;
|
private Map<String, String> organization;
|
||||||
|
private List<Map<String, String>> organizations;
|
||||||
private List<Long> fragmentIds = List.of();
|
private List<Long> fragmentIds = List.of();
|
||||||
private boolean fail;
|
private boolean fail;
|
||||||
|
|
||||||
@@ -207,6 +222,9 @@ class OrgSnapshotEnterpriseKnowledgeAccessPolicyTest {
|
|||||||
return phone == null ? List.of() : mapRows(rowMapper, List.of(Map.of("phonenumber", phone)));
|
return phone == null ? List.of() : mapRows(rowMapper, List.of(Map.of("phonenumber", phone)));
|
||||||
}
|
}
|
||||||
if (sql.contains("FROM aihr_org_snapshot")) {
|
if (sql.contains("FROM aihr_org_snapshot")) {
|
||||||
|
if (organizations != null) {
|
||||||
|
return mapRows(rowMapper, new ArrayList<>(organizations));
|
||||||
|
}
|
||||||
return organization == null ? List.of() : mapRows(rowMapper, List.of(organization));
|
return organization == null ? List.of() : mapRows(rowMapper, List.of(organization));
|
||||||
}
|
}
|
||||||
if (sql.contains("FROM aihr_knowledge_acl")) {
|
if (sql.contains("FROM aihr_knowledge_acl")) {
|
||||||
|
|||||||
Reference in New Issue
Block a user