diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index d92ab55..f881002 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -1,9 +1,9 @@
-name: Continuous Integration for User Service
+name: Continuous Integration for Comment Service
on:
push:
branches:
- - main
+ - ducbao
jobs:
testing:
@@ -26,11 +26,11 @@ jobs:
- name: Unit Tests
run: mvn -B test --file pom.xml
-# sonar-cloud-scan:
-# needs: testing
-# uses: ./.github/workflows/SonarQube.yaml
-# secrets:
-# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ # sonar-cloud-scan:
+ # needs: testing
+ # uses: ./.github/workflows/SonarQube.yaml
+ # secrets:
+ # SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
build-image:
needs: testing
@@ -38,12 +38,12 @@ jobs:
secrets:
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
-# scan-image:
-# needs: build-image
-# uses: ./.github/workflows/scan-image.yaml
+ # scan-image:
+ # needs: build-image
+ # uses: ./.github/workflows/scan-image.yaml
-# notify:
-# needs: scan-image
-# uses: ./.github/workflows/notifyCI.yaml
-# secrets:
-# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
+ # notify:
+ # needs: scan-image
+ # uses: ./.github/workflows/notifyCI.yaml
+ # secrets:
+ # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
diff --git a/.gitignore b/.gitignore
index 8ff02c9..549e00a 100755
--- a/.gitignore
+++ b/.gitignore
@@ -31,4 +31,3 @@ build/
### VS Code ###
.vscode/
-#logback-*.xml
\ No newline at end of file
diff --git a/README.md b/README.md
index fe4f062..267c7d5 100644
--- a/README.md
+++ b/README.md
@@ -29,4 +29,3 @@ The backend of this streaming project exposes the following API endpoints:
"# UserService"
-# UserService-NT548
diff --git a/pom.xml b/pom.xml
index 02dbe9f..c450841 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,39 +82,6 @@
gson
2.10.1
-
- io.jsonwebtoken
- jjwt-api
- 0.11.5
-
-
- io.jsonwebtoken
- jjwt-impl
- 0.11.5
- runtime
-
-
- io.jsonwebtoken
- jjwt-jackson
- 0.11.5
- runtime
-
-
-
-
-
-
- redis.clients
- jedis
- 5.1.0
-
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
- 3.2.4
-
-
net.logstash.logback
diff --git a/resources.yaml b/resources.yaml
deleted file mode 100644
index c4edba2..0000000
--- a/resources.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: user-service
- labels:
- app: user-service
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: user-service
- template:
- metadata:
- labels:
- app: user-service
- spec:
- containers:
- - name: user-service
- image: datuits/devops-user-service:latest
- ports:
- - containerPort: 8081
- env:
- - name: SPRING_DATA_MONGODB_URI
- value: mongodb://user-mongo-service:27017/user-service
- resources:
- requests:
- memory: "32Mi"
- cpu: "0.2"
- limits:
- memory: "64Mi"
- cpu: "0.4"
----
-apiVersion: v1
-kind: Service
-metadata:
- name: user-service
-spec:
- selector:
- app: user-service
- ports:
- - protocol: TCP
- port: 8081
- targetPort: 8081
- type: NodePort
\ No newline at end of file
diff --git a/src/main/java/com/programming/userService/config/JwtRequestFilter.java b/src/main/java/com/programming/userService/config/JwtRequestFilter.java
deleted file mode 100644
index 787c269..0000000
--- a/src/main/java/com/programming/userService/config/JwtRequestFilter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.programming.userService.config;
-
-import com.programming.userService.util.JwtUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-import java.io.IOException;
-
-@Component
-public class JwtRequestFilter extends OncePerRequestFilter {
-
- @Autowired
- private UserDetailsService userDetailsService;
-
- @Autowired
- private JwtUtil jwtUtil;
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
- throws ServletException, IOException {
-
- final String authorizationHeader = request.getHeader("Authorization");
-
- String username = null;
- String jwt = null;
-
- if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
- jwt = authorizationHeader.substring(7);
- username = jwtUtil.extractUsername(jwt);
- }
-
- if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
-
- UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
-
- if (jwtUtil.validateToken(jwt, userDetails)) {
-
- UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
- userDetails, null, userDetails.getAuthorities());
- usernamePasswordAuthenticationToken
- .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
- SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
- }
- }
- chain.doFilter(request, response);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/programming/userService/config/RedisConfig.java b/src/main/java/com/programming/userService/config/RedisConfig.java
deleted file mode 100644
index e56cce5..0000000
--- a/src/main/java/com/programming/userService/config/RedisConfig.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.programming.userService.config;
-
-import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
-import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
-import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-import org.springframework.beans.factory.annotation.Value;
-@Configuration
-@EnableRedisRepositories
-public class RedisConfig {
-
- @Value("${spring.redis.host}")
- private String redisHost;
-
- @Value("${spring.redis.port}")
- private int redisPort;
-
- @Value("${spring.redis.password}")
- private String redisPassword;
-
- @Bean
- public RedisConnectionFactory redisConnectionFactory() {
- RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
- redisConfig.setHostName(redisHost);
- redisConfig.setPort(redisPort);
- redisConfig.setPassword(redisPassword);
-
- return new LettuceConnectionFactory(redisConfig);
- }
-
-
- @Bean
- public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
- RedisTemplate template = new RedisTemplate<>();
- template.setConnectionFactory(connectionFactory);
- template.setKeySerializer(new StringRedisSerializer());
- template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
- return template;
- }
-}
diff --git a/src/main/java/com/programming/userService/config/SecurityConfig.java b/src/main/java/com/programming/userService/config/SecurityConfig.java
index 8b60bb0..998a2ec 100644
--- a/src/main/java/com/programming/userService/config/SecurityConfig.java
+++ b/src/main/java/com/programming/userService/config/SecurityConfig.java
@@ -12,7 +12,6 @@
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.util.ArrayList;
import java.util.Collection;
@@ -22,26 +21,25 @@ public class SecurityConfig {
@Bean
public SecurityFilterChain defaultFilterChain(HttpSecurity httpSecurity) throws Exception {
- JwtRequestFilter jwtRequestFilter = new JwtRequestFilter();
return httpSecurity
.csrf(csrf -> csrf.disable())
- .authorizeHttpRequests(auth -> auth.requestMatchers("/user/register", "/user/error").permitAll()
- // .requestMatchers("/listUser").permitAll()
- .requestMatchers("/user/login2").permitAll()
- .requestMatchers("/user/login3").permitAll()
- .requestMatchers("/user/listUserbyId/**").permitAll()
- .requestMatchers("/user/hello-world").permitAll()
- .requestMatchers("/user/send-verification-email").permitAll()
- .requestMatchers("/user/logout").permitAll()
- .requestMatchers("/user/listUserbyUsername").permitAll()
- .requestMatchers("/user/listUserbyId/**").permitAll()
- .requestMatchers("/user/updateProfile/**").permitAll()
- .requestMatchers("/user/changePassword/**").permitAll()
- .requestMatchers("/user/listUser").permitAll()
-
- .requestMatchers("/user/").authenticated()
+ .authorizeHttpRequests(auth -> auth.requestMatchers("/register", "/error").permitAll()
+ .requestMatchers("/listUser").permitAll()
+ .requestMatchers("/video/upload").permitAll()
+ .requestMatchers("/video/list").permitAll()
+ .requestMatchers("/file/upload").permitAll()
+ .requestMatchers("/file/list").permitAll()
+ .requestMatchers("/file/downloadZipFile").permitAll()
+ .requestMatchers("/comments/upload").permitAll()
+ .requestMatchers("/comments/**").permitAll()
+ .requestMatchers("/video/**").permitAll()
+ .requestMatchers("/login2").permitAll()
+ .requestMatchers("/listUserbyId/**").permitAll()
+ .requestMatchers("/updateProfile/**").permitAll()
+ .requestMatchers("/send-verification-email").permitAll()
+ .requestMatchers("/hello-world").permitAll()
+ .requestMatchers("/**").permitAll()
.anyRequest().authenticated())
- .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
.httpBasic(Customizer.withDefaults())
.formLogin(Customizer.withDefaults())
.build();
diff --git a/src/main/java/com/programming/userService/controller/UserController.java b/src/main/java/com/programming/userService/controller/UserController.java
index aa5496a..ad9f4c2 100644
--- a/src/main/java/com/programming/userService/controller/UserController.java
+++ b/src/main/java/com/programming/userService/controller/UserController.java
@@ -22,10 +22,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-
-import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.annotation.Cacheable;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
@@ -33,13 +30,10 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import com.programming.userService.util.JwtUtil;
-import com.programming.userService.entity.CustomUserDetails;
-import com.programming.userService.entity.AuthUser;
-import org.springframework.data.redis.core.RedisTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
@RestController
@AllArgsConstructor
@@ -48,13 +42,8 @@ public class UserController {
private final AuthUserRepository userRepository;
private final PasswordEncoder passwordEncoder;
- private final RedisTemplate redisTemplate;
- private static final String USER_CACHE = "USER_CACHE";
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
- @Autowired
- private JwtUtil jwtUtil;
-
@Autowired
private JavaMailSender javaMailSender;
@@ -67,9 +56,6 @@ public String getEmail() {
}
@GetMapping("/")
public String getServiceName(){
- //ELK
- MDC.put("type", "userservice");
- logger.info("User Service Start");
return "User Service";
}
@@ -115,34 +101,12 @@ public ResponseEntity registerUser(@RequestBody AuthUser user) {
private byte[] getDefaultAvatar() throws IOException {
String defaultAvatarPath = "/app/images/avatar.png"; // Path inside the Docker container
- //String defaultAvatarPath = "src/main/java/com/programming/userService/images/avatar.png"; // Path on local machine
Path path = Paths.get(defaultAvatarPath);
return Files.readAllBytes(path);
}
- @PostMapping("/login3")
- public ResponseEntity> loginUser3(@RequestBody AuthUser user) {
- try {
- AuthUser userFromDb = userRepository.findByUsername(user.getUsername())
- .orElseThrow(() -> new Exception("User not found"));
-
- if (passwordEncoder.matches(user.getPassword(), userFromDb.getPassword())) {
- // Chuyển AuthUser sang CustomUserDetails
- CustomUserDetails userDetails = new CustomUserDetails(userFromDb);
- String token = jwtUtil.generateToken(userDetails); // Tạo JWT token với UserDetails
- Map response = new HashMap<>();
- response.put("token", token);
- return ResponseEntity.ok(response);
- } else {
- return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
- }
- } catch (Exception e) {
- return ResponseEntity.internalServerError().body(e.getMessage());
- }
- }
-
@PostMapping("/login2")
- public ResponseEntity loginUser2(@RequestBody AuthUser user) {
+ public ResponseEntity loginUser(@RequestBody AuthUser user) {
try {
AuthUser userFromDb = userRepository.findByUsername(user.getUsername())
.orElseThrow(() -> new Exception("User not found"));
@@ -186,27 +150,10 @@ public ResponseEntity listUserbyUsername(@RequestBody AuthUser user) {
}
}
- @Cacheable(value = USER_CACHE, key = "#id")
@GetMapping("/listUserbyId/{id}")
public ResponseEntity listUserbyId(@PathVariable("id") String id) {
try {
- // Attempt to fetch user from Redis cache
- AuthUser cachedUser = (AuthUser) redisTemplate.opsForHash().get(USER_CACHE, id);
-
- if (cachedUser != null) {
- // If user is found in Redis, return it
- return ResponseEntity.ok(cachedUser);
- }
-
- // If user is not found in Redis, fetch from MongoDB
- AuthUser user = userRepository.findById(id)
- .orElseThrow(() -> new Exception("User not found"));
-
- // Cache the user in Redis
- redisTemplate.opsForHash().put(USER_CACHE, id, user);
-
- // Return the user data
- return ResponseEntity.ok(user);
+ return ResponseEntity.ok(userRepository.findById(id));
} catch (Exception e) {
return ResponseEntity.internalServerError().body(e.getMessage());
}
@@ -221,12 +168,9 @@ public ResponseEntity updateProfile(@PathVariable("id") String id, @RequestBody
userFromDb.setFirstName(user.getFirstName());
userFromDb.setLastName(user.getLastName());
AuthUser save = userRepository.save(userFromDb);
- String tempUserId = userFromDb.getId();
-
MDC.put("type", "userservice");
MDC.put("action", "update-profile");
logger.info("UserID: " + userFromDb.getId());
-
return ResponseEntity.ok(HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.internalServerError().body(e.getMessage());
@@ -246,11 +190,9 @@ public ResponseEntity changePassword(@PathVariable("id") String id,
userFromDb.setPassword(passwordEncoder.encode(changePasswordRequest.getNewPassword()));
AuthUser save = userRepository.save(userFromDb);
-
MDC.put("type", "userservice");
MDC.put("action", "change-password");
logger.info("UserID: " + userFromDb.getId());
-
return ResponseEntity.ok("Password changed successfully");
} catch (Exception e) {
return ResponseEntity.internalServerError().body(e.getMessage());
diff --git a/src/main/java/com/programming/userService/entity/AuthUser.java b/src/main/java/com/programming/userService/entity/AuthUser.java
index b145c1b..0a031e4 100644
--- a/src/main/java/com/programming/userService/entity/AuthUser.java
+++ b/src/main/java/com/programming/userService/entity/AuthUser.java
@@ -7,12 +7,11 @@
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
-import java.io.Serializable;
@Data
@Builder
@Document("user")
-public class AuthUser implements Serializable {
+public class AuthUser {
@Id
private String id;
@Indexed
@@ -25,7 +24,4 @@ public class AuthUser implements Serializable {
private byte[] avatar;
private String email;
private Date timestamp;
-
-
- private static final long serialVersionUID = 1L;
}
diff --git a/src/main/java/com/programming/userService/entity/CustomUserDetails.java b/src/main/java/com/programming/userService/entity/CustomUserDetails.java
deleted file mode 100644
index fe8a276..0000000
--- a/src/main/java/com/programming/userService/entity/CustomUserDetails.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.programming.userService.entity;
-
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-import java.util.Collection;
-import java.util.Collections;
-
-public class CustomUserDetails implements UserDetails {
-
- private final AuthUser authUser;
-
- public CustomUserDetails(AuthUser authUser) {
- this.authUser = authUser;
- }
-
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- return Collections.emptyList(); // Thêm danh sách quyền nếu cần thiết
- }
-
- @Override
- public String getPassword() {
- return authUser.getPassword();
- }
-
- @Override
- public String getUsername() {
- return authUser.getUsername();
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return true;
- }
-}
diff --git a/src/main/java/com/programming/userService/util/JwtUtil.java b/src/main/java/com/programming/userService/util/JwtUtil.java
deleted file mode 100644
index c7ea8e8..0000000
--- a/src/main/java/com/programming/userService/util/JwtUtil.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.programming.userService.util;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.stereotype.Service;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-
-
-@Service
-public class JwtUtil {
- private String SECRET_KEY = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; // Thay đổi SECRET_KEY với giá trị bảo mật của bạn
-
- public String extractUsername(String token) {
- return extractClaim(token, Claims::getSubject);
- }
-
- public Date extractExpiration(String token) {
- return extractClaim(token, Claims::getExpiration);
- }
-
- public T extractClaim(String token, Function claimsResolver) {
- final Claims claims = extractAllClaims(token);
- return claimsResolver.apply(claims);
- }
-
- private Claims extractAllClaims(String token) {
- return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
- }
-
- private Boolean isTokenExpired(String token) {
- return extractExpiration(token).before(new Date());
- }
-
- public String generateToken(UserDetails userDetails) {
- Map claims = new HashMap<>();
- return createToken(claims, userDetails.getUsername());
- }
-
- private String createToken(Map claims, String subject) {
- return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
- .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // Token có hiệu lực trong 10
- // giờ
- .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
- }
-
- public Boolean validateToken(String token, UserDetails userDetails) {
- final String username = extractUsername(token);
- return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
- }
-}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 511a171..2705ff0 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -19,9 +19,6 @@ spring.mail.password=vkux umrv rtkd svsy
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
+
# logstash
-logging.config=classpath:logback-spring.xml
-# Redis
-spring.redis.host=localhost
-spring.redis.port=6379
-spring.redis.password=
\ No newline at end of file
+logging.config=classpath:logback-spring.xml
\ No newline at end of file
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
index 6b0ebf7..982fc84 100644
--- a/src/main/resources/logback-spring.xml
+++ b/src/main/resources/logback-spring.xml
@@ -4,7 +4,6 @@
-
diff --git a/src/test/java/TestUserService.java b/src/test/java/TestUserService.java
index 672144b..edff7ed 100644
--- a/src/test/java/TestUserService.java
+++ b/src/test/java/TestUserService.java
@@ -1,19 +1,19 @@
-// import org.junit.jupiter.api.Test;
-// import org.springframework.beans.factory.annotation.Autowired;
-// import org.springframework.test.web.servlet.MockMvc;
-// import org.springframework.boot.test.context.SpringBootTest;
-// import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-// import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-// import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-// @SpringBootTest(classes = com.programming.userService.StreamingApplication.class)
-// @AutoConfigureMockMvc
-// public class TestUserService {
-// @Autowired
-// private MockMvc mockMvc;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+@SpringBootTest(classes = com.programming.userService.StreamingApplication.class)
+@AutoConfigureMockMvc
+public class TestUserService {
+ @Autowired
+ private MockMvc mockMvc;
-// @Test
-// public void testGetServiceName() throws Exception {
-// mockMvc.perform(get("/user/"))
-// .andExpect(status().isOk());
-// }
-// }
+ @Test
+ public void testGetServiceName() throws Exception {
+ mockMvc.perform(get("/user/"))
+ .andExpect(status().isOk());
+ }
+}