Skip to content

Commit

Permalink
Add endpoint for loading book pages by ID
Browse files Browse the repository at this point in the history
  • Loading branch information
jsharkey13 committed Feb 7, 2025
1 parent 64920d1 commit 9ed7f83
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/java/uk/ac/cam/cl/dtg/isaac/api/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ public enum IsaacServerLogType implements LogType {
UPDATE_QUIZ_FEEDBACK_MODE,
VIEW_ASSIGNMENT_PROGRESS,
VIEW_CONCEPT,
VIEW_BOOK_PAGE,
VIEW_MY_BOARDS_PAGE,
VIEW_PAGE,
VIEW_PAGE_FRAGMENT,
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/uk/ac/cam/cl/dtg/isaac/api/PagesFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import uk.ac.cam.cl.dtg.isaac.dos.QuestionValidationResponse;
import uk.ac.cam.cl.dtg.isaac.dos.content.Content;
import uk.ac.cam.cl.dtg.isaac.dto.GameboardDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacBookPageDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacConceptPageDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacPageFragmentDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacQuestionPageDTO;
Expand Down Expand Up @@ -850,6 +851,64 @@ public final Response getPageFragment(@Context final Request request,
}
}

/**
* Endpoint that gets a single book index page from the given id.
*
* @param request
* - so that we can deal with caching.
* @param httpServletRequest
* - so that we can extract user information.
* @param bookId
* as a string
* @return A Response object containing a page fragment object or containing a SegueErrorResponse.
*/
@GET
@Path("/books/{book_id}")
@Produces(MediaType.APPLICATION_JSON)
@GZIP
@Operation(summary = "Get a book index page by ID.")
public final Response getBookPage(@Context final Request request,
@Context final HttpServletRequest httpServletRequest,
@PathParam("book_id") final String bookId) {

// Calculate the ETag on current live version of the content
EntityTag etag = new EntityTag(String.valueOf(this.contentManager.getCurrentContentSHA().hashCode() + bookId.hashCode()));
Response cachedResponse = generateCachedResponse(request, etag);
if (cachedResponse != null) {
return cachedResponse;
}

try {
ContentDTO contentDTO = contentManager.getContentById(bookId, true);
if (contentDTO instanceof IsaacBookPageDTO) {
// Unlikely we want to augment with related content here!

// Log the page view:
getLogManager().logEvent(userManager.getCurrentUser(httpServletRequest), httpServletRequest,
IsaacServerLogType.VIEW_BOOK_PAGE, ImmutableMap.of(
PAGE_ID_LOG_FIELDNAME, bookId,
CONTENT_VERSION_FIELDNAME, this.contentManager.getCurrentContentSHA()
));

return Response.ok(contentDTO)
.cacheControl(getCacheControl(NUMBER_SECONDS_IN_ONE_HOUR, true))
.tag(etag)
.build();
} else {
log.warn("Unable to locate a book page with the id '{}'!", bookId);

Check failure

Code scanning / CodeQL

Log Injection High

This log entry depends on a
user-provided value
.
return SegueErrorResponse.getResourceNotFoundResponse("Unable to locate a book page with the id specified!");
}
} catch (SegueDatabaseException e) {
SegueErrorResponse error = new SegueErrorResponse(Status.INTERNAL_SERVER_ERROR, "Database error while processing request.");
log.error(error.getErrorMessage(), e);
return error.toResponse();
} catch (ContentManagerException e) {
SegueErrorResponse error = new SegueErrorResponse(Status.INTERNAL_SERVER_ERROR, "Error locating the content requested");
log.error(error.getErrorMessage(), e);
return error.toResponse();
}
}

/**
* Rest endpoint retrieving the first MAX_PODS_TO_RETURN pods by ID.
*
Expand Down

0 comments on commit 9ed7f83

Please sign in to comment.