Skip to content

Commit

Permalink
Merge branch 'dev' into CSCEXAM-1214
Browse files Browse the repository at this point in the history
  • Loading branch information
lupari authored Dec 13, 2023
2 parents 00e6add + a3796ad commit 008574f
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 291 deletions.
6 changes: 1 addition & 5 deletions app/controllers/AttachmentController.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
import org.apache.pekko.stream.javadsl.FileIO;
import org.apache.pekko.stream.javadsl.Source;
import org.apache.pekko.util.ByteString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.libs.Files;
import play.mvc.Http;
import play.mvc.Http.MultipartFormData.FilePart;
Expand All @@ -52,8 +50,6 @@

public class AttachmentController extends BaseController implements LocalAttachmentInterface {

private final Logger logger = LoggerFactory.getLogger(AttachmentController.class);

@Inject
private ConfigReader configReader;

Expand All @@ -68,7 +64,7 @@ public CompletionStage<Result> addAttachmentToQuestionAnswer(Http.Request reques
FilePart<Files.TemporaryFile> filePart = mf.getFilePart();
long qid = Long.parseLong(mf.getForm().get("questionId")[0]);

// first check if answer already exist
// first check if answer already exists
ExamSectionQuestion question = DB
.find(ExamSectionQuestion.class)
.fetch("essayAnswer")
Expand Down
56 changes: 24 additions & 32 deletions app/controllers/CourseController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,25 @@
package controllers

import impl.ExternalCourseHandler
import io.ebean.DB
import models.{Course, Role, User}
import org.joda.time.DateTime
import io.ebean.DB
import javax.inject.Inject
import play.api.mvc.{Action, AnyContent, InjectedController, Result}
import security.Authenticator
import security.scala.Auth.{AuthenticatedAction, authorized}
import security.scala.{Auth, AuthExecutionContext}
import util.config.ConfigReader
import util.scala.JavaJsonResultProducer

import scala.jdk.FutureConverters._
import scala.concurrent.ExecutionContext.Implicits.global
import javax.inject.Inject
import scala.concurrent.Future
import scala.jdk.CollectionConverters._
import scala.jdk.FutureConverters._

class CourseController @Inject()(externalApi: ExternalCourseHandler, configReader: ConfigReader)
class CourseController @Inject()(externalApi: ExternalCourseHandler,
configReader: ConfigReader,
authenticated: AuthenticatedAction,
implicit val ec: AuthExecutionContext)
extends InjectedController
with Authenticator
with JavaJsonResultProducer {

def listCourses(filterType: Option[String],
Expand Down Expand Up @@ -68,9 +70,9 @@ class CourseController @Inject()(externalApi: ExternalCourseHandler, configReade
}

private def getUserCourses(user: User,
examIds: Option[List[Long]],
sectionIds: Option[List[Long]],
tagIds: Option[List[Long]]): Result = {
examIds: Option[List[Long]],
sectionIds: Option[List[Long]],
tagIds: Option[List[Long]]): Result = {
var query = DB.find(classOf[Course]).where.isNotNull("name")
if (!user.hasRole(Role.Name.ADMIN)) {
query = query
Expand All @@ -90,34 +92,24 @@ class CourseController @Inject()(externalApi: ExternalCourseHandler, configReade
}

// Actions ->

def getCourses(filterType: Option[String], criteria: Option[String]): Action[AnyContent] =
Action.async { request =>
getAuthorizedUser(request, Seq("ADMIN", "TEACHER")) match {
case Some(user) =>
listCourses(filterType, criteria, user)
case _ =>
Future.successful(forbid())
}
def getCourses(filterType: Option[String], criteria: Option[String]): Action[AnyContent] = {
authenticated.andThen(authorized(Seq(Role.Name.ADMIN, Role.Name.TEACHER))).async { request =>
val user = request.attrs(Auth.ATTR_USER)
listCourses(filterType, criteria, user)
}
}

def getCourse(id: Long): Action[AnyContent] = Action { request =>
getAuthorizedUser(request, Seq("ADMIN", "TEACHER")) match {
case Some(_) =>
DB.find(classOf[Course], id).toResult(OK)
case _ => forbid()
def getCourse(id: Long): Action[AnyContent] =
Action.andThen(authorized(Seq(Role.Name.TEACHER, Role.Name.ADMIN))) { _ =>
DB.find(classOf[Course], id).toResult(OK)
}
}

def listUsersCourses(examIds: Option[List[Long]],
sectionIds: Option[List[Long]],
tagIds: Option[List[Long]]): Action[AnyContent] = Action { request =>
getAuthorizedUser(request, Seq("ADMIN", "TEACHER")) match {
case Some(user) =>
getUserCourses(user, examIds, sectionIds, tagIds)
case _ =>
forbid()
tagIds: Option[List[Long]]): Action[AnyContent] =
authenticated.andThen(authorized(Seq(Role.Name.TEACHER, Role.Name.ADMIN))) { request =>
val user = request.attrs(Auth.ATTR_USER)
getUserCourses(user, examIds, sectionIds, tagIds)
}
}

}
6 changes: 3 additions & 3 deletions app/controllers/ExamMachineController.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ public Result removeExamMachine(Long id) {
}

@Restrict({ @Group("TEACHER"), @Group("ADMIN"), @Group("STUDENT") })
public Result getSoftwares() {
List<Software> softwares = DB
public Result listSoftware() {
List<Software> software = DB
.find(Software.class)
.where()
.or()
Expand All @@ -179,7 +179,7 @@ public Result getSoftwares() {
.endOr()
.findList();

return ok(softwares);
return ok(software);
}

@Restrict({ @Group("TEACHER"), @Group("ADMIN") })
Expand Down
15 changes: 7 additions & 8 deletions app/controllers/LanguageInspectionController.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,6 @@ public Result assignInspection(Long id, Http.Request request) {
}

private Optional<Result> checkInspection(LanguageInspection inspection) {
if (inspection == null) {
return Optional.of(notFound("Inspection not found"));
}
if (inspection.getStartedAt() == null) {
return Optional.of(forbidden("Inspection not assigned"));
}
Expand All @@ -153,13 +150,12 @@ public Result setApproval(Long id, Http.Request request) {
DynamicForm df = formFactory.form().bindFromRequest(request);
boolean isApproved = Boolean.parseBoolean(df.get("approved"));
LanguageInspection inspection = DB.find(LanguageInspection.class, id);
if (inspection == null) {
return notFound("Inspection not found");
}
return checkInspection(inspection)
.orElseGet(() -> {
if (
inspection == null ||
inspection.getStatement() == null ||
inspection.getStatement().getComment().isEmpty()
) {
if (inspection.getStatement() == null || inspection.getStatement().getComment().isEmpty()) {
return forbidden("No statement given");
}
inspection.setFinishedAt(new Date());
Expand Down Expand Up @@ -196,6 +192,9 @@ public Result setStatement(Long id, Http.Request request) {
return badRequest();
}
LanguageInspection inspection = DB.find(LanguageInspection.class, id);
if (inspection == null) {
return notFound("Inspection not found");
}
return checkInspection(inspection)
.orElseGet(() -> {
User user = request.attrs().get(Attrs.AUTHENTICATED_USER);
Expand Down
34 changes: 19 additions & 15 deletions app/controllers/QuestionReviewController.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,8 @@ public Result getEssays(Long examId, Optional<List<Long>> ids, Http.Request requ
.filter(question -> questionIds.isEmpty() || questionIds.contains(question.getId()))
.toList();

// Comparator for ordering questions, have to take to account that answer's question is no longer found
Comparator<Question> comparator = (o1, o2) -> {
List<Long> l = questionSequence.stream().map(GeneratedIdentityModel::getId).toList();
if (!l.contains(o1.getId())) {
return 1;
}
if (!l.contains(o2.getId())) {
return -1;
}
return l.indexOf(o1.getId()) - l.indexOf(o2.getId());
};

// Ordered map of questions to answers
Map<Question, List<ExamSectionQuestion>> questionMap = new TreeMap<>(comparator);
// Ordered map for questions, have to take to account that answer's question is no longer found
Map<Question, List<ExamSectionQuestion>> questionMap = createMapping(questionSequence);

// All the answers for questions in this exam
List<ExamSectionQuestion> answers = exam
Expand All @@ -104,7 +92,7 @@ public Result getEssays(Long examId, Optional<List<Long>> ids, Http.Request requ
.filter(esq -> questionIds.isEmpty() || questionIds.contains(esq.getQuestion().getParent().getId()))
.toList();

// Get evaluation criterias from parent exam section questions
// Get evaluation criteria from parent exam section questions
Map<Question, String> evaluationCriteriaMap = exam
.getExamSections()
.stream()
Expand Down Expand Up @@ -143,6 +131,22 @@ public Result getEssays(Long examId, Optional<List<Long>> ids, Http.Request requ
return writeAnonymousResult(request, ok(json).as("application/json"), exam.isAnonymous());
}

private static Map<Question, List<ExamSectionQuestion>> createMapping(List<Question> questions) {
Comparator<Question> comparator = (o1, o2) -> {
List<Long> ids = questions.stream().map(GeneratedIdentityModel::getId).toList();
if (!ids.contains(o1.getId())) {
return 1;
}
if (!ids.contains(o2.getId())) {
return -1;
}
return ids.indexOf(o1.getId()) - ids.indexOf(o2.getId());
};

// Ordered map of questions to answers
return new TreeMap<>(comparator);
}

// DTO
private static class QuestionEntry {

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/ReportController.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public String getState() {
}

private boolean applyExamFilter(Exam e, Optional<String> start, Optional<String> end) {
Boolean result = e.getState().ordinal() > Exam.State.PUBLISHED.ordinal() && e.getExamParticipation() != null;
boolean result = e.getState().ordinal() > Exam.State.PUBLISHED.ordinal() && e.getExamParticipation() != null;
DateTime created = e.getCreated();
if (start.isPresent()) {
DateTime startDate = DateTime.parse(start.get(), ISODateTimeFormat.dateTimeParser());
Expand Down
Loading

0 comments on commit 008574f

Please sign in to comment.