Add API for updating role and goal for users (#8242)
This commit is contained in:
parent
470fab30f7
commit
a4975c5bff
|
|
@ -9,6 +9,7 @@ import com.appsmith.server.dtos.ResetUserPasswordDTO;
|
|||
import com.appsmith.server.dtos.ResponseDTO;
|
||||
import com.appsmith.server.dtos.UserProfileDTO;
|
||||
import com.appsmith.server.dtos.UserSignupRequestDTO;
|
||||
import com.appsmith.server.dtos.UserUpdateDTO;
|
||||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.services.UserDataService;
|
||||
import com.appsmith.server.services.UserOrganizationService;
|
||||
|
|
@ -92,8 +93,8 @@ public class UserController extends BaseController<UserService, User, String> {
|
|||
}
|
||||
|
||||
@PutMapping()
|
||||
public Mono<ResponseDTO<User>> update(@RequestBody User resource, ServerWebExchange exchange) {
|
||||
return service.updateCurrentUser(resource, exchange)
|
||||
public Mono<ResponseDTO<User>> update(@RequestBody UserUpdateDTO updates, ServerWebExchange exchange) {
|
||||
return service.updateCurrentUser(updates, exchange)
|
||||
.map(updatedUser -> new ResponseDTO<>(HttpStatus.OK.value(), updatedUser, null));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ public class UserProfileDTO {
|
|||
|
||||
CommentOnboardingState commentOnboardingState;
|
||||
|
||||
String role;
|
||||
|
||||
String useCase;
|
||||
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.isEnabled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.appsmith.server.dtos;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Includes **only** those fields that can be updated for a user, via an API call.
|
||||
*/
|
||||
@Data
|
||||
public class UserUpdateDTO {
|
||||
|
||||
private String name;
|
||||
|
||||
private String role;
|
||||
|
||||
private String useCase;
|
||||
|
||||
public boolean hasUserUpdates() {
|
||||
return name != null;
|
||||
}
|
||||
|
||||
public boolean hasUserDataUpdates() {
|
||||
return role != null || useCase != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ public interface UserDataService {
|
|||
|
||||
Mono<UserData> getForUserEmail(String email);
|
||||
|
||||
Mono<UserData> updateForCurrentUser(UserData updates);
|
||||
|
||||
Mono<UserData> updateForUser(User user, UserData updates);
|
||||
|
||||
Mono<User> setViewedCurrentVersionReleaseNotes(User user);
|
||||
|
|
|
|||
|
|
@ -100,20 +100,16 @@ public class UserDataServiceImpl extends BaseService<UserDataRepository, UserDat
|
|||
.flatMap(this::getForUser);
|
||||
}
|
||||
|
||||
private Mono<UserData> updateForCurrentUser(UserData updates) {
|
||||
@Override
|
||||
public Mono<UserData> updateForCurrentUser(UserData updates) {
|
||||
return sessionUserService.getCurrentUser()
|
||||
.flatMap(user -> userRepository.findByEmail(user.getEmail()))
|
||||
.flatMap(user -> {
|
||||
// If a UserData document exists for this user, update it. If not, create one.
|
||||
updates.setUserId(user.getId());
|
||||
final Mono<UserData> updaterMono = update(user.getId(), updates);
|
||||
final Mono<UserData> creatorMono = Mono.just(updates).flatMap(this::create);
|
||||
return updaterMono.switchIfEmpty(creatorMono);
|
||||
});
|
||||
.flatMap(user -> updateForUser(user, updates));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<UserData> updateForUser(User user, UserData updates) {
|
||||
// If a UserData document exists for this user, update it. If not, create one.
|
||||
updates.setUserId(user.getId());
|
||||
final Mono<UserData> updaterMono = update(user.getId(), updates);
|
||||
final Mono<UserData> creatorMono = Mono.just(updates).flatMap(this::create);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.appsmith.server.dtos.InviteUsersDTO;
|
|||
import com.appsmith.server.dtos.ResetUserPasswordDTO;
|
||||
import com.appsmith.server.dtos.UserProfileDTO;
|
||||
import com.appsmith.server.dtos.UserSignupDTO;
|
||||
import com.appsmith.server.dtos.UserUpdateDTO;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ public interface UserService extends CrudService<User, String> {
|
|||
|
||||
Mono<List<User>> inviteUsers(InviteUsersDTO inviteUsersDTO, String originHeader);
|
||||
|
||||
Mono<User> updateCurrentUser(User updates, ServerWebExchange exchange);
|
||||
Mono<User> updateCurrentUser(UserUpdateDTO updates, ServerWebExchange exchange);
|
||||
|
||||
Map<String, String> getEmailParams(Organization organization, User inviterUser, String inviteUrl, boolean isNewUser);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.appsmith.server.dtos.InviteUsersDTO;
|
|||
import com.appsmith.server.dtos.ResetUserPasswordDTO;
|
||||
import com.appsmith.server.dtos.UserProfileDTO;
|
||||
import com.appsmith.server.dtos.UserSignupDTO;
|
||||
import com.appsmith.server.dtos.UserUpdateDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.helpers.PolicyUtils;
|
||||
|
|
@ -818,19 +819,37 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
|
|||
}
|
||||
|
||||
@Override
|
||||
public Mono<User> updateCurrentUser(User allUpdates, ServerWebExchange exchange) {
|
||||
// Not all fields can be updated. We only let a few fields of a User object be updated with this method.
|
||||
final User allowedUpdates = new User();
|
||||
allowedUpdates.setName(allUpdates.getName());
|
||||
public Mono<User> updateCurrentUser(final UserUpdateDTO allUpdates, ServerWebExchange exchange) {
|
||||
List<Mono<Void>> monos = new ArrayList<>();
|
||||
|
||||
return sessionUserService.getCurrentUser()
|
||||
.flatMap(user ->
|
||||
update(user.getEmail(), allowedUpdates, fieldName(QUser.user.email))
|
||||
.then(exchange == null
|
||||
? repository.findByEmail(user.getEmail())
|
||||
: sessionUserService.refreshCurrentUser(exchange))
|
||||
)
|
||||
.map(userChangedHandler::publish);
|
||||
Mono<User> updatedUserMono;
|
||||
|
||||
if (allUpdates.hasUserUpdates()) {
|
||||
final User updates = new User();
|
||||
updates.setName(allUpdates.getName());
|
||||
updatedUserMono = sessionUserService.getCurrentUser()
|
||||
.flatMap(user ->
|
||||
update(user.getEmail(), updates, fieldName(QUser.user.email))
|
||||
.then(exchange == null
|
||||
? repository.findByEmail(user.getEmail())
|
||||
: sessionUserService.refreshCurrentUser(exchange))
|
||||
)
|
||||
.map(userChangedHandler::publish)
|
||||
.cache();
|
||||
monos.add(updatedUserMono.then());
|
||||
} else {
|
||||
updatedUserMono = sessionUserService.getCurrentUser()
|
||||
.flatMap(user -> findByEmail(user.getEmail()));
|
||||
}
|
||||
|
||||
if (allUpdates.hasUserDataUpdates()) {
|
||||
final UserData updates = new UserData();
|
||||
updates.setRole(allUpdates.getRole());
|
||||
updates.setUseCase(allUpdates.getUseCase());
|
||||
monos.add(userDataService.updateForCurrentUser(updates).then());
|
||||
}
|
||||
|
||||
return Mono.whenDelayError(monos).then(updatedUserMono);
|
||||
}
|
||||
|
||||
public Map<String, String> getEmailParams(Organization organization, User inviter, String inviteUrl, boolean isNewUser) {
|
||||
|
|
@ -882,6 +901,8 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
|
|||
profile.setAnonymous(user.isAnonymous());
|
||||
profile.setEnabled(user.isEnabled());
|
||||
profile.setCommentOnboardingState(userData.getCommentOnboardingState());
|
||||
profile.setRole(userData.getRole());
|
||||
profile.setUseCase(userData.getUseCase());
|
||||
|
||||
profile.setSuperUser(policyUtils.isPermissionPresentForUser(
|
||||
userFromDb.getPolicies(),
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ import com.appsmith.server.domains.LoginSource;
|
|||
import com.appsmith.server.domains.Organization;
|
||||
import com.appsmith.server.domains.PasswordResetToken;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.domains.UserData;
|
||||
import com.appsmith.server.dtos.InviteUsersDTO;
|
||||
import com.appsmith.server.dtos.ResetUserPasswordDTO;
|
||||
import com.appsmith.server.dtos.UserSignupDTO;
|
||||
import com.appsmith.server.dtos.UserUpdateDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
import com.appsmith.server.repositories.PasswordResetTokenRepository;
|
||||
|
|
@ -39,6 +41,7 @@ import org.springframework.util.LinkedCaseInsensitiveMap;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
|
|
@ -83,6 +86,9 @@ public class UserServiceTest {
|
|||
@Autowired
|
||||
EncryptionService encryptionService;
|
||||
|
||||
@Autowired
|
||||
UserDataService userDataService;
|
||||
|
||||
@MockBean
|
||||
PasswordResetTokenRepository passwordResetTokenRepository;
|
||||
|
||||
|
|
@ -457,10 +463,8 @@ public class UserServiceTest {
|
|||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void updateNameOfUser() {
|
||||
User updateUser = new User();
|
||||
updateUser.setEmail("api_user");
|
||||
UserUpdateDTO updateUser = new UserUpdateDTO();
|
||||
updateUser.setName("New name of api_user");
|
||||
|
||||
StepVerifier.create(userService.updateCurrentUser(updateUser, null))
|
||||
.assertNext(user -> {
|
||||
assertNotNull(user);
|
||||
|
|
@ -470,6 +474,46 @@ public class UserServiceTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void updateRoleOfUser() {
|
||||
UserUpdateDTO updateUser = new UserUpdateDTO();
|
||||
updateUser.setRole("New role of user");
|
||||
final Mono<UserData> resultMono = userService.updateCurrentUser(updateUser, null)
|
||||
.then(userDataService.getForUserEmail("api_user"));
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(userData -> {
|
||||
assertNotNull(userData);
|
||||
assertThat(userData.getRole()).isEqualTo("New role of user");
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void updateNameRoleAndUseCaseOfUser() {
|
||||
UserUpdateDTO updateUser = new UserUpdateDTO();
|
||||
updateUser.setName("New name of user here");
|
||||
updateUser.setRole("New role of user");
|
||||
updateUser.setUseCase("New use case");
|
||||
final Mono<Tuple2<User, UserData>> resultMono = userService.updateCurrentUser(updateUser, null)
|
||||
.flatMap(user -> Mono.zip(
|
||||
Mono.just(user),
|
||||
userDataService.getForUserEmail("api_user")
|
||||
));
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(tuple -> {
|
||||
final User user = tuple.getT1();
|
||||
final UserData userData = tuple.getT2();
|
||||
assertNotNull(user);
|
||||
assertNotNull(userData);
|
||||
assertThat(user.getName()).isEqualTo("New name of user here");
|
||||
assertThat(userData.getRole()).isEqualTo("New role of user");
|
||||
assertThat(userData.getUseCase()).isEqualTo("New use case");
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createUserAndSendEmail_WhenUserExistsWithEmailInOtherCase_ThrowsException() {
|
||||
User existingUser = new User();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user