fix(aihr): bind practice sessions to owner
This commit is contained in:
+2
-2
@@ -131,12 +131,12 @@ public class AihrPracticeController {
|
||||
|
||||
@PostMapping("/turn")
|
||||
public R<TurnResponse> turn(@RequestBody TurnRequest request) {
|
||||
return R.ok(practiceSeedService.turn(request));
|
||||
return R.ok(practiceSeedService.turn(request, currentAppUsername()));
|
||||
}
|
||||
|
||||
@PostMapping("/finish")
|
||||
public R<FinishResponse> finish(@RequestBody FinishRequest request) {
|
||||
return R.ok(practiceSeedService.finish(request));
|
||||
return R.ok(practiceSeedService.finish(request, currentAppUsername()));
|
||||
}
|
||||
|
||||
@SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, HR_OPERATOR_ROLE}, mode = SaMode.OR)
|
||||
|
||||
+27
-1
@@ -494,8 +494,15 @@ public class AihrPracticeSeedService {
|
||||
}
|
||||
|
||||
public TurnResponse turn(TurnRequest request) {
|
||||
return turn(request, "");
|
||||
}
|
||||
|
||||
public TurnResponse turn(TurnRequest request, String ownerIdentity) {
|
||||
String style = normalizeRegenerateStyle(request == null ? null : request.style());
|
||||
ActiveSession session = request == null || isBlank(request.sessionId()) ? null : activeSessions.get(request.sessionId());
|
||||
if (!isBlank(ownerIdentity)) {
|
||||
requireSessionOwner(session, ownerIdentity);
|
||||
}
|
||||
ScenarioSeed scenario = resolveScenario(session == null ? null : session.scenarioId(), request == null ? null : request.sessionId());
|
||||
int roundIndex = normalizeRoundIndex(request == null ? null : request.roundIndex(), scenario.rounds().size());
|
||||
if (request != null && Boolean.TRUE.equals(request.regenerate())) {
|
||||
@@ -630,8 +637,19 @@ public class AihrPracticeSeedService {
|
||||
}
|
||||
|
||||
public FinishResponse finish(FinishRequest request) {
|
||||
return finish(request, "");
|
||||
}
|
||||
|
||||
public FinishResponse finish(FinishRequest request, String ownerIdentity) {
|
||||
String sessionId = request == null ? null : request.sessionId();
|
||||
ActiveSession activeSession = sessionId == null ? null : activeSessions.remove(sessionId);
|
||||
ActiveSession activeSession;
|
||||
if (isBlank(ownerIdentity)) {
|
||||
activeSession = sessionId == null ? null : activeSessions.remove(sessionId);
|
||||
} else {
|
||||
ActiveSession existing = sessionId == null ? null : activeSessions.get(sessionId);
|
||||
requireSessionOwner(existing, ownerIdentity);
|
||||
activeSession = activeSessions.remove(sessionId);
|
||||
}
|
||||
ScenarioSeed scenario = resolveScenario(activeSession == null ? null : activeSession.scenarioId(), sessionId);
|
||||
String trainee = activeSession == null ? scenario.trainee() : activeSession.trainee();
|
||||
PracticeResult result = evaluate(activeSession, scenario);
|
||||
@@ -1896,6 +1914,14 @@ public class AihrPracticeSeedService {
|
||||
return request.extPartyId().trim();
|
||||
}
|
||||
|
||||
private static void requireSessionOwner(ActiveSession session, String ownerIdentity) {
|
||||
String owner = ownerIdentity == null ? "" : ownerIdentity.trim();
|
||||
String sessionOwner = session == null || session.extPartyId() == null ? "" : session.extPartyId().trim();
|
||||
if (session == null || !owner.equals(sessionOwner)) {
|
||||
throw new ServiceException("训练会话不存在或无权访问");
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveTrainee(StartRequest request, ScenarioSeed scenario) {
|
||||
if (!isMobile(request) || request.extPartyId() == null || request.extPartyId().isBlank()) {
|
||||
return scenario.trainee();
|
||||
|
||||
+28
@@ -2,8 +2,11 @@ package org.dromara.aihr.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.CompetencyResponse;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.FinishRequest;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.PracticeAssignmentRequest;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.ReviewAdviceRequest;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.StartRequest;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.TurnRequest;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -106,6 +109,31 @@ public class AihrPracticeSeedServiceTest {
|
||||
assertEquals("缺少员工ID,无法派发专项训练", error.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mobilePracticeSessionRejectsForeignAndUnknownOwner() {
|
||||
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
|
||||
when(jdbcTemplate.query(contains("SELECT scenario_code"), any(RowMapper.class), eq("000000"), eq("complaint-water")))
|
||||
.thenReturn(List.of());
|
||||
AihrPracticeSeedService service = new AihrPracticeSeedService(new ObjectMapper(), jdbcTemplate, null, null);
|
||||
var ownerSession = service.start(new StartRequest("employee-a", "complaint-water", "mobile", null));
|
||||
var otherSession = service.start(new StartRequest("employee-b", "complaint-water", "mobile", null));
|
||||
|
||||
ServiceException foreign = assertThrows(ServiceException.class, () -> service.turn(
|
||||
new TurnRequest(otherSession.sessionId(), 0, "越权回答", null, null, false, null), "employee-a"
|
||||
));
|
||||
assertEquals("训练会话不存在或无权访问", foreign.getMessage());
|
||||
|
||||
ServiceException unknown = assertThrows(ServiceException.class, () -> service.finish(
|
||||
new FinishRequest("seed-not-started", null), "employee-a"
|
||||
));
|
||||
assertEquals("训练会话不存在或无权访问", unknown.getMessage());
|
||||
|
||||
ServiceException missing = assertThrows(ServiceException.class, () -> service.finish(
|
||||
new FinishRequest(ownerSession.sessionId(), null), "employee-other"
|
||||
));
|
||||
assertEquals("训练会话不存在或无权访问", missing.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAssignmentRejectsOutOfProjectAssignee() {
|
||||
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
|
||||
|
||||
Reference in New Issue
Block a user