Merge branch 'feature/user-profile' into 'release'

Modifying the user profile endpoint to send organization and application details

For event tracking, we need the organization name and application names that a user is accessing. In order to reduce the number of API calls, we are returning this information along with the enhanced user profile API call `/profile`. Another endpoint was added instead of `/me` to maintain backwards compatibility.


See merge request theappsmith/internal-tools-server!213
This commit is contained in:
Arpit Mohan 2020-03-06 06:17:01 +00:00
commit 89dec71a07
6 changed files with 86 additions and 1 deletions

View File

@ -5,6 +5,7 @@ import com.appsmith.server.domains.InviteUser;
import com.appsmith.server.domains.User;
import com.appsmith.server.dtos.ResetUserPasswordDTO;
import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.dtos.UserProfileDTO;
import com.appsmith.server.services.SessionUserService;
import com.appsmith.server.services.UserOrganizationService;
import com.appsmith.server.services.UserService;
@ -77,12 +78,19 @@ public class UserController extends BaseController<UserService, User, String> {
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}
@Deprecated
@GetMapping("/me")
public Mono<ResponseDTO<User>> getUserProfile() {
return sessionUserService.getCurrentUser()
.map(user -> new ResponseDTO<>(HttpStatus.OK.value(), user, null));
}
@GetMapping("/profile")
public Mono<ResponseDTO<UserProfileDTO>> getEnhancedUserProfile() {
return service.getUserProfile()
.map(user -> new ResponseDTO<>(HttpStatus.OK.value(), user, null));
}
/**
* This function creates an invite for a new user to join the Appsmith platform. We require the Origin header
* in order to construct client facing URLs that will be sent to the user via email.

View File

@ -1,11 +1,13 @@
package com.appsmith.server.domains;
import com.appsmith.external.models.BaseDomain;
import com.appsmith.server.dtos.ApplicationNameIdDTO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.core.GrantedAuthority;
@ -14,6 +16,7 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

View File

@ -0,0 +1,13 @@
package com.appsmith.server.dtos;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ApplicationNameIdDTO {
String id;
String name;
}

View File

@ -0,0 +1,19 @@
package com.appsmith.server.dtos;
import com.appsmith.server.domains.Organization;
import com.appsmith.server.domains.User;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class UserProfileDTO {
User user;
Organization currentOrganization;
List<ApplicationNameIdDTO> applications;
}

View File

@ -3,6 +3,7 @@ package com.appsmith.server.services;
import com.appsmith.server.domains.InviteUser;
import com.appsmith.server.domains.User;
import com.appsmith.server.dtos.ResetUserPasswordDTO;
import com.appsmith.server.dtos.UserProfileDTO;
import reactor.core.publisher.Mono;
public interface UserService extends CrudService<User, String> {
@ -22,4 +23,6 @@ public interface UserService extends CrudService<User, String> {
Mono<Boolean> verifyInviteToken(String email, String token);
Mono<Boolean> confirmInviteUser(InviteUser inviteUser);
Mono<UserProfileDTO> getUserProfile();
}

View File

@ -1,21 +1,26 @@
package com.appsmith.server.services;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.InviteUser;
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.dtos.ApplicationNameIdDTO;
import com.appsmith.server.dtos.ResetUserPasswordDTO;
import com.appsmith.server.dtos.UserProfileDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.helpers.BeanCopyUtils;
import com.appsmith.server.notifications.EmailSender;
import com.appsmith.server.repositories.ApplicationRepository;
import com.appsmith.server.repositories.InviteUserRepository;
import com.appsmith.server.repositories.PasswordResetTokenRepository;
import com.appsmith.server.repositories.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
@ -49,6 +54,7 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
private final GroupService groupService;
private final InviteUserRepository inviteUserRepository;
private final UserOrganizationService userOrganizationService;
private final ApplicationRepository applicationRepository;
private static final String WELCOME_USER_EMAIL_TEMPLATE = "email/welcomeUserTemplate.html";
private static final String INVITE_USER_EMAIL_TEMPLATE = "email/inviteUserTemplate.html";
@ -70,7 +76,8 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
EmailSender emailSender,
GroupService groupService,
InviteUserRepository inviteUserRepository,
UserOrganizationService userOrganizationService) {
UserOrganizationService userOrganizationService,
ApplicationRepository applicationRepository) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
this.repository = repository;
this.organizationService = organizationService;
@ -82,6 +89,7 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
this.groupService = groupService;
this.inviteUserRepository = inviteUserRepository;
this.userOrganizationService = userOrganizationService;
this.applicationRepository = applicationRepository;
}
@Override
@ -487,4 +495,35 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
// Doesn't work without this.
.map(user -> (UserDetails) user);
}
@Override
public Mono<UserProfileDTO> getUserProfile() {
return sessionUserService.getCurrentUser()
.flatMap(user -> {
String currentOrganizationId = user.getCurrentOrganizationId();
UserProfileDTO userProfile = new UserProfileDTO();
userProfile.setUser(user);
Mono<UserProfileDTO> userProfileDTOMono = organizationService.findById(currentOrganizationId)
.flatMap(org -> {
userProfile.setCurrentOrganization(org);
Application applicationExample = new Application();
applicationExample.setOrganizationId(org.getId());
return applicationRepository.findAll(Example.of(applicationExample))
.map(application -> {
ApplicationNameIdDTO dto = new ApplicationNameIdDTO();
dto.setId(application.getId());
dto.setName(application.getName());
return dto;
}).collectList()
.map(dtos -> {
userProfile.setApplications(dtos);
return userProfile;
});
});
return userProfileDTOMono;
});
}
}