Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions common-events/src/main/java/events/user/UserEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package events.user;

import events.user.data.UserPayload;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserEvent {
Type type;
String id; // userId
UserPayload payload; // null nếu DELETED

public enum Type { CREATED, UPDATED, DELETED, RESTORED }
}
21 changes: 21 additions & 0 deletions common-events/src/main/java/events/user/UserRegisteredEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package events.user;

import events.user.data.UserPayload;
import events.user.data.UserProfileCreationPayload;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserRegisteredEvent {
String id;
UserPayload user;
UserProfileCreationPayload profile;
}
27 changes: 27 additions & 0 deletions common-events/src/main/java/events/user/data/UserPayload.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package events.user.data;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;

import java.time.Instant;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserPayload {
String userId; // id của identity -> dùng làm @Id trong profile
String username;
String email;
boolean active; // enabled của identity

Set<String> roles; // ["ADMIN","USER",...]
Instant createdAt;
Instant updatedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package events.user.data;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;

import java.time.Instant;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserProfileCreationPayload {
String firstName;
String lastName;
Instant dob;
String bio;
Boolean gender;
String displayName;
Integer education;
String[] links;
String city;
}
6 changes: 6 additions & 0 deletions identity-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.codecampus</groupId>
<artifactId>common-events</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.codecampus.identity.configuration.config.init;

import com.codecampus.identity.dto.request.profile.UserProfileCreationRequest;
import com.codecampus.identity.entity.account.Role;
import com.codecampus.identity.entity.account.User;
import com.codecampus.identity.mapper.kafka.UserPayloadMapper;
import com.codecampus.identity.repository.account.PermissionRepository;
import com.codecampus.identity.repository.account.RoleRepository;
import com.codecampus.identity.repository.account.UserRepository;
import com.codecampus.identity.repository.httpclient.profile.ProfileClient;
import com.codecampus.identity.service.kafka.UserEventProducer;
import com.codecampus.identity.utils.ConvertUtils;
import events.user.data.UserProfileCreationPayload;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
Expand All @@ -32,11 +34,19 @@ public class ApplicationInitializationService {
RoleRepository roleRepository;
PermissionRepository permissionRepository;
UserRepository userRepository;

PasswordEncoder passwordEncoder;
ProfileClient profileClient;

UserPayloadMapper userPayloadMapper;

UserEventProducer userEventProducer;

@Transactional
void createAdminUser(String username, String password, String email) {
void createAdminUser(
String username,
String password,
String email) {
Role adminRole = checkRoleAndCreate(ADMIN_ROLE);

Set<Role> roles = new HashSet<>();
Expand All @@ -50,9 +60,10 @@ void createAdminUser(String username, String password, String email) {
.roles(roles)
.build());

profileClient.internalCreateUserProfile(
UserProfileCreationRequest.builder()
.userId(user.getId())
userEventProducer.publishCreatedUserEvent(user);

UserProfileCreationPayload payload =
UserProfileCreationPayload.builder()
.firstName("Admin")
.lastName("Sys")
.dob(ConvertUtils.parseDdMmYyyyToInstant("28/03/2004"))
Expand All @@ -63,8 +74,9 @@ void createAdminUser(String username, String password, String email) {
.links(new String[] {"https://github.com/yunomix2834",
"https://github.com/CapstoneProjectCMC/backend"})
.city("Vietnam")
.build()
);
.build();

userEventProducer.publishRegisteredUserEvent(user, payload);
}

@Transactional
Expand All @@ -82,9 +94,10 @@ void createUser(String username, String password, String email) {
.roles(roles)
.build());

profileClient.internalCreateUserProfile(
UserProfileCreationRequest.builder()
.userId(user.getId())
userEventProducer.publishCreatedUserEvent(user);

UserProfileCreationPayload payload =
UserProfileCreationPayload.builder()
.firstName("Code")
.lastName("Campus")
.dob(ConvertUtils.parseDdMmYyyyToInstant("28/03/2004"))
Expand All @@ -95,8 +108,9 @@ void createUser(String username, String password, String email) {
.links(new String[] {"https://github.com/yunomix2834",
"https://github.com/CapstoneProjectCMC/backend"})
.city("Vietnam")
.build()
);
.build();

userEventProducer.publishRegisteredUserEvent(user, payload);
}

Role checkRoleAndCreate(String roleName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.codecampus.identity.configuration.kafka;

import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;

import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableKafka
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class KafkaProducerConfig {
Environment env;

@Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
env.getProperty("spring.kafka.bootstrap-servers",
"localhost:9092"));
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
StringSerializer.class);
props.put(ProducerConfig.ACKS_CONFIG, "all");
return new DefaultKafkaProducerFactory<>(props);
}

@Bean
public KafkaTemplate<String, String> kafkaTemplate(
ProducerFactory<String, String> factory) {
return new KafkaTemplate<>(factory);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.codecampus.identity.controller.authentication;

import com.codecampus.identity.dto.common.ApiResponse;
import com.codecampus.identity.dto.request.authentication.ChangeEmailRequest;
import com.codecampus.identity.dto.request.authentication.ChangeEmailVerifyRequest;
import com.codecampus.identity.service.authentication.EmailChangeService;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@Builder
@Slf4j
@RequestMapping("/user/email")
public class EmailChangeController {

EmailChangeService emailChangeService;

@PostMapping("/change/request")
public ApiResponse<Void> request(
@RequestBody ChangeEmailRequest changeEmailRequest) {
emailChangeService.requestChangeEmail(changeEmailRequest);
return ApiResponse.<Void>builder()
.message("OTP đã gửi tới email mới")
.build();
}

@PostMapping("/change/verify")
public ApiResponse<Void> verify(
@RequestBody ChangeEmailVerifyRequest changeEmailVerifyRequest) {
emailChangeService.verifyOtp(changeEmailVerifyRequest);
emailChangeService.verifyOtp(changeEmailVerifyRequest);
return ApiResponse.<Void>builder()
.message("Đổi email thành công")
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ public class UserController {

@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/user")
ApiResponse<UserResponse> createUser(
ApiResponse<Void> createUser(
@RequestBody @Valid UserCreationRequest request) {
return ApiResponse.<UserResponse>builder()
.result(userService.createUser(request))
userService.createUser(request);
return ApiResponse.<Void>builder()
.message("Create User successful")
.build();
}
Expand Down Expand Up @@ -92,20 +92,20 @@ ApiResponse<String> deleteUser(

@PreAuthorize("hasRole('ADMIN')")
@PutMapping("/user/{userId}")
ApiResponse<UserResponse> updateUser(
ApiResponse<Void> updateUser(
@PathVariable("userId") String userId,
@RequestBody UserUpdateRequest request) {
return ApiResponse.<UserResponse>builder()
.result(userService.updateUser(userId, request))
userService.updateUserById(userId, request);
return ApiResponse.<Void>builder()
.message("Update User successful")
.build();
}

@PutMapping("/user/my-info")
ApiResponse<UserResponse> updateMyInfo(
ApiResponse<Void> updateMyInfo(
UserUpdateRequest request) {
return ApiResponse.<UserResponse>builder()
.result(userService.updateMyInfo(request))
userService.updateMyInfo(request);
return ApiResponse.<Void>builder()
.message("Update My Info successful")
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.codecampus.identity.dto.request.authentication;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChangeEmailRequest {
String newEmail;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.codecampus.identity.dto.request.authentication;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChangeEmailVerifyRequest {
String newEmail;
String otpCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class User extends AuditMetadata {

@PreRemove
private void doSoftDelete() {
this.setDeletedBy(AuthenticationHelper.getMyEmail());
this.setDeletedBy(AuthenticationHelper.getMyUsername());
this.setDeletedAt(Instant.now());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@
@Mapper(componentModel = "spring",
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface UserMapper {
User toUser(UserCreationRequest userCreationRequest);
User toUserFromUserCreationRequest(UserCreationRequest userCreationRequest);

@Mapping(target = "userId", ignore = true)
UserProfileCreationRequest toUserProfileCreationRequest(
UserCreationRequest req);
UserProfileCreationRequest toUserProfileCreationRequestFromUserCreationRequest(
UserCreationRequest userCreationRequest);

UserResponse toUserResponse(User user);
UserResponse toUserResponseFromUser(
User user);

@Mapping(target = "roles", ignore = true)
void updateUser(
void updateUserUpdateRequestToUser(
@MappingTarget User user,
UserUpdateRequest userUpdateRequest
);
Expand Down
Loading