Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
07236b9
feat: add creation of users by token
Juan-Rpenuela May 9, 2025
3d29270
feat: complete implemetation jwt
Juan-Rpenuela May 9, 2025
6b17199
fix: merge conflicts
Juan-Rpenuela May 13, 2025
bd0c849
docs(api): document recommendation and goal services
LePeanutButter May 13, 2025
6d04b01
feat(reports): add dynamic report export with format and userId param…
LePeanutButter May 13, 2025
573ffe2
chore: update CI-CD-Production.yml
AnderssonProgramming May 14, 2025
9357c54
feat:implemented security and role management inside the endpoints
Juan-Rpenuela May 15, 2025
77849c6
feat: change format double number for duariont
cris-eci May 16, 2025
669b3ee
Merge pull request #22 from AnderssonProgramming/feature/reports-and-…
cris-eci May 18, 2025
f737cc8
Merge branch 'develop' of https://github.com/AnderssonProgramming/Pro…
AnderssonProgramming May 18, 2025
5c869ea
test: add new report service Impl and report enum tests to pass code …
AnderssonProgramming May 18, 2025
7eca694
Merge pull request #23 from AnderssonProgramming/feature/add_unit_tests
AnderssonProgramming May 18, 2025
78f1542
fix: merge conflicts and UserController unit test
Juan-Rpenuela May 21, 2025
1625572
docs: add complete README specifying all the features, design, and co…
AnderssonProgramming May 23, 2025
4a6d96f
Merge pull request #24 from AnderssonProgramming/feature/add_README
AnderssonProgramming May 23, 2025
5710264
docs: add react-next.js into new sprint in README
AnderssonProgramming May 23, 2025
f7d6d1a
Merge pull request #25 from AnderssonProgramming/feature/add_README
AnderssonProgramming May 23, 2025
3d4b874
docs: update README.md to delete TO-DO info
AnderssonProgramming May 23, 2025
2749580
fix: permission with endpoint create
Juan-Rpenuela May 24, 2025
c5badd2
Merge branch 'develop' into fix/security-MergeConflicts
cris-eci May 24, 2025
08ac975
fix: merge problems with develop
Juan-Rpenuela May 24, 2025
e11eb41
Merge pull request #27 from AnderssonProgramming/fix/security-MergeCo…
AnderssonProgramming May 24, 2025
7e53828
fix(cors): set Access-Control-Allow-Origin correctly
LePeanutButter May 25, 2025
5ea7956
fix(user): map institutionalId correctly to database column
LePeanutButter May 25, 2025
9472624
fix(auth): resolve permission issue for session queries
LePeanutButter May 25, 2025
f0ce764
merge pull request #28 from AnderssonProgramming/fix/fix-cors-issues
Juan-Rpenuela May 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,087 changes: 1,085 additions & 2 deletions README.md

Large diffs are not rendered by default.

Binary file added assets/Gym-Module-C4-Code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Gym-Module-C4-Components.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Gym-Module-C4-Containers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Gym-Module-C4-Context.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 19 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,21 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>


<!-- PDFBox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.30</version>
</dependency>

<!-- Apache POI para Excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
Expand Down Expand Up @@ -171,8 +185,10 @@
<artifactId>dotenv-java</artifactId>
<version>2.3.1</version>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>

<dependencyManagement>
Expand Down
9 changes: 4 additions & 5 deletions src/main/java/edu/eci/cvds/prometeo/config/CorsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@

@Configuration
public class CorsConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(@SuppressWarnings("null") CorsRegistry registry) {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // Cambiar el origen al necesario
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(false);
.allowCredentials(true);
}
}
80 changes: 80 additions & 0 deletions src/main/java/edu/eci/cvds/prometeo/config/JwtRequestFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package edu.eci.cvds.prometeo.config;

import edu.eci.cvds.prometeo.util.JwtUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

private final JwtUtil jwtUtil;

public JwtRequestFilter(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
throws ServletException, IOException {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}

final String authHeader = request.getHeader("Authorization");

System.out.println("🔍 Checking Authorization header...");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
System.out.println("✅ Authorization header found: " + authHeader);

try {
var claims = jwtUtil.extractClaims(authHeader);

String username = claims.get("userName", String.class);
String role = claims.get("role", String.class).toUpperCase();
String name = claims.get("name", String.class);
String idCard = claims.get("id", String.class);

// Log extracted claims
System.out.println("✅ JWT Claims extracted:");
System.out.println("username = " + username);
System.out.println("role = " + role);
System.out.println("name = " + name);
System.out.println("idCard = " + idCard);

// Save attributes in the request
request.setAttribute("username", username);
request.setAttribute("role", role);
request.setAttribute("name", name);
request.setAttribute("institutionalId", idCard);

// Set authentication in SecurityContext
var authorities = List.of(new SimpleGrantedAuthority("ROLE_" + role));
var auth = new UsernamePasswordAuthenticationToken(username, null, authorities);
SecurityContextHolder.getContext().setAuthentication(auth);

} catch (Exception e) {
System.out.println("❌ Error extracting JWT claims: " + e.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
return;
}
} else {
System.out.println("⚠️ Authorization header is missing or does not start with 'Bearer '");
}

chain.doFilter(request, response);
System.out.println("🔍 Post-filter role: " + request.getAttribute("role"));
}
}
24 changes: 24 additions & 0 deletions src/main/java/edu/eci/cvds/prometeo/config/LoggingFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package edu.eci.cvds.prometeo.config;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

public class LoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
System.out.println("🔍 Request URI: " + request.getRequestURI());
System.out.println("🔍 Method: " + request.getMethod());
System.out.println("🔍 All Attributes: ");
request.getAttributeNames().asIterator().forEachRemaining(attr ->
System.out.println(attr + " = " + request.getAttribute(attr))
);
filterChain.doFilter(request, response);
}
}
49 changes: 40 additions & 9 deletions src/main/java/edu/eci/cvds/prometeo/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
package edu.eci.cvds.prometeo.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

@Slf4j
@Configuration
@EnableWebSecurity
public class SecurityConfig {


private final JwtRequestFilter jwtRequestFilter;

public SecurityConfig(JwtRequestFilter jwtRequestFilter) {
this.jwtRequestFilter = jwtRequestFilter;
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// Configuración que desactiva toda la seguridad
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/**").permitAll()
)
.formLogin(form -> form.disable())
.httpBasic(basic -> basic.disable());

.cors(cors -> {})
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/users/create").authenticated()
.requestMatchers("/api/users/trainer/sessions").hasAnyRole("STUDENT", "TRAINER")
.requestMatchers("/api/users/trainer/**").hasRole("TRAINER")
.anyRequest().hasAnyRole("TRAINER", "STUDENT", "ADMIN")
)
.formLogin(form -> form.disable())
.httpBasic(basic -> basic.disable())
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new LoggingFilter(), JwtRequestFilter.class);
return http.build();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("http://localhost:3000"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.setAllowedHeaders(List.of("*"));
config.setAllowCredentials(true);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
Loading