Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into chore/actions-fixing
Browse files Browse the repository at this point in the history
  • Loading branch information
dariogmori committed Mar 3, 2024
2 parents c3b2455 + 91e4730 commit 4265a1c
Show file tree
Hide file tree
Showing 51 changed files with 969 additions and 210 deletions.
5 changes: 5 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/lab/en2b/quizapi/auth/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
@Service
@RequiredArgsConstructor
public class AuthService {
private final JwtUtils jwtUtils;
private final AuthenticationManager authenticationManager;
private final UserService userService;
private final JwtUtils jwtUtils;
/**
* Creates a session for a user. Throws an 401 unauthorized exception otherwise
* @param loginRequest the request containing the login info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Collections;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
Expand All @@ -38,7 +40,7 @@ public CorsFilter corsFilter() {
// Configure CORS settings here
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.setAllowedOriginPatterns(Collections.singletonList("*"));
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package lab.en2b.quizapi.auth.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
@EqualsAndHashCode
public class JwtResponseDto {
private String token;
@JsonProperty("refresh_token")
Expand Down
5 changes: 5 additions & 0 deletions api/src/main/java/lab/en2b/quizapi/auth/dtos/LoginDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package lab.en2b.quizapi.auth.dtos;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -10,7 +12,10 @@
@Data
public class LoginDto {
@NonNull
@NotBlank
@Email
private String email;
@NonNull
@NotBlank
private String password;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lab.en2b.quizapi.auth.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -10,7 +11,8 @@
@NoArgsConstructor
@Data
public class RefreshTokenDto {
@NonNull
@JsonProperty("refresh_token")
@NonNull
@NotEmpty
private String refreshToken;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package lab.en2b.quizapi.auth.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class RefreshTokenResponseDto {

private String token;
Expand Down
6 changes: 6 additions & 0 deletions api/src/main/java/lab/en2b/quizapi/auth/dtos/RegisterDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package lab.en2b.quizapi.auth.dtos;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -9,10 +11,14 @@
@NoArgsConstructor
@Data
public class RegisterDto {
@NotBlank
@NonNull
@Email
private String email;
@NonNull
@NotBlank
private String username;
@NonNull
@NotBlank
private String password;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
@Log4j2
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomControllerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(InvalidAuthenticationException.class)
public ResponseEntity<String> handleInvalidAuthenticationException(InvalidAuthenticationException exception){
log.error(exception.getMessage(),exception);
return new ResponseEntity<>(exception.getMessage(),HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(NoSuchElementException.class)
public ResponseEntity<String> handleNoSuchElementException(NoSuchElementException exception){
log.error(exception.getMessage(),exception);
Expand Down Expand Up @@ -50,7 +55,7 @@ public ResponseEntity<String> handleTokenRefreshException(TokenRefreshException
@ExceptionHandler(InternalAuthenticationServiceException.class)
public ResponseEntity<String> handleInternalAuthenticationServiceException(InternalAuthenticationServiceException exception) {
log.error(exception.getMessage(),exception);
return new ResponseEntity<>(exception.getMessage(),HttpStatus.FORBIDDEN);
return new ResponseEntity<>(exception.getMessage(),HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception exception){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package lab.en2b.quizapi.commons.exceptions;

public class InvalidAuthenticationException extends RuntimeException{
public InvalidAuthenticationException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lab.en2b.quizapi.auth.config.UserDetailsImpl;
import lab.en2b.quizapi.auth.dtos.RegisterDto;
import lab.en2b.quizapi.commons.exceptions.InvalidAuthenticationException;
import lab.en2b.quizapi.commons.user.role.RoleRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -23,10 +24,10 @@ public class UserService implements UserDetailsService {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
@Value("${REFRESH_TOKEN_DURATION_MS}")
private Long REFRESH_TOKEN_DURATION_MS;
private long REFRESH_TOKEN_DURATION_MS;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return UserDetailsImpl.build(userRepository.findByEmail(email).orElseThrow());
return UserDetailsImpl.build(userRepository.findByEmail(email).orElseThrow(() -> new InvalidAuthenticationException("Invalid email or password provided!")));
}
public void createUser(RegisterDto registerRequest, Set<String> roleNames){
if (userRepository.existsByEmail(registerRequest.getEmail()) || userRepository.existsByUsername(registerRequest.getUsername())) {
Expand Down
13 changes: 13 additions & 0 deletions api/src/main/java/lab/en2b/quizapi/commons/utils/TestUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package lab.en2b.quizapi.commons.utils;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TestUtils {
public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
28 changes: 28 additions & 0 deletions api/src/main/java/lab/en2b/quizapi/questions/answer/Answer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package lab.en2b.quizapi.questions.answer;

import jakarta.persistence.*;
import lab.en2b.quizapi.questions.question.Question;
import lombok.*;

import java.util.List;

@Entity
@Table(name = "answers")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;
private String text;
private AnswerCategory category;
@OneToMany(mappedBy = "correctAnswer", fetch = FetchType.EAGER)
private List<Question> questions;

@ManyToMany(mappedBy = "answers", fetch = FetchType.EAGER)
private List<Question> questionsWithThisAnswer;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package lab.en2b.quizapi.questions.answer;

public enum AnswerCategory {
CITY, COUNTRY, PERSON, EVENT, DATE, OTHER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package lab.en2b.quizapi.questions.answer.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class AnswerDto {
@JsonProperty("answer_id")
private Long answerId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package lab.en2b.quizapi.questions.answer.dtos;

import lab.en2b.quizapi.questions.answer.AnswerCategory;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class AnswerResponseDto {
private Long id;
private String text;
private AnswerCategory category;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package lab.en2b.quizapi.questions.answer.mappers;

import lab.en2b.quizapi.questions.answer.Answer;
import lab.en2b.quizapi.questions.answer.dtos.AnswerResponseDto;
import org.springframework.stereotype.Service;

import java.util.function.Function;

@Service
public class AnswerResponseDtoMapper implements Function<Answer, AnswerResponseDto> {
@Override
public AnswerResponseDto apply(Answer answer) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package lab.en2b.quizapi.questions.question;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lab.en2b.quizapi.questions.answer.Answer;
import lab.en2b.quizapi.questions.answer.AnswerCategory;
import lombok.*;

import java.util.List;

@Entity
@Table(name = "questions")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Question {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;
private String content;
@NotNull
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name="questions_answers",
joinColumns=
@JoinColumn(name="question_id", referencedColumnName="id"),
inverseJoinColumns=
@JoinColumn(name="answer_id", referencedColumnName="id")
)
private List<Answer> answers;
@ManyToOne
@JoinColumn(name = "correct_answer_id")
private Answer correctAnswer;
private QuestionCategory questionCategory;
private AnswerCategory answerCategory;
private String language;
private QuestionType type;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package lab.en2b.quizapi.questions.question;

public enum QuestionCategory {
HISTORY, GEOGRAPHY, SCIENCE, MATH, LITERATURE, ART, SPORTS, MUSIC, MOVIES, TV, POLITICS, OTHER
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
package lab.en2b.quizapi.questions.question;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lab.en2b.quizapi.questions.answer.dtos.AnswerDto;
import lab.en2b.quizapi.questions.question.dtos.AnswerCheckResponseDto;
import lab.en2b.quizapi.questions.question.dtos.QuestionResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/questions")
@RequiredArgsConstructor
public class QuestionController {
@GetMapping("/dummy")
private String getDummyQuestion(){
return "Who the hell is Steve Jobs?";
private final QuestionService questionService;

// TODO: REMOVE WHEN NOT USED FOR TESTING
@GetMapping
private ResponseEntity<List<QuestionResponseDto>> getQuestions() {
return ResponseEntity.ok(questionService.getQuestions());
}

@PostMapping("/{questionId}/answer")
private ResponseEntity<AnswerCheckResponseDto> answerQuestion(@PathVariable Long questionId, @RequestBody AnswerDto answerDto){
return ResponseEntity.ok(questionService.answerQuestion(questionId,answerDto));
}

@GetMapping("/new")
private ResponseEntity<QuestionResponseDto> generateQuestion(){
return ResponseEntity.ok(questionService.getQuestion());
}

@GetMapping("/{id}")
private ResponseEntity<QuestionResponseDto> getQuestionById(@PathVariable Long id){
return ResponseEntity.ok(questionService.getQuestionById(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package lab.en2b.quizapi.questions.question;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface QuestionRepository extends JpaRepository<Question,Long> {
@Query(value = "SELECT * FROM questions ORDER BY RAND() LIMIT 1", nativeQuery = true)
Question findRandomQuestion();
}
Loading

0 comments on commit 4265a1c

Please sign in to comment.