Skip to content

User manangement api #1464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 29, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.lowcoder.api.usermanagement.view.OrgView;
import org.lowcoder.api.usermanagement.view.UpdateOrgRequest;
import org.lowcoder.api.usermanagement.view.UpdateRoleRequest;
import org.lowcoder.domain.organization.model.OrgMember;
import org.lowcoder.domain.organization.model.Organization;
import org.lowcoder.domain.organization.model.Organization.OrganizationCommonSettings;
import org.lowcoder.infra.annotation.NonEmptyMono;
Expand All @@ -23,8 +24,12 @@ public interface OrgApiService {

Mono<Boolean> updateRoleForMember(String orgId, UpdateRoleRequest updateRoleRequest);

Mono<OrgMember> checkVisitorAdminRole(String orgId);

Mono<Boolean> switchCurrentOrganizationTo(String orgId);

Mono<Boolean> switchCurrentOrganizationTo(String userId, String orgId);

Mono<Boolean> deleteLogo(String orgId);

Mono<Boolean> uploadLogo(String orgId, Mono<Part> fileMono);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ public Mono<Boolean> updateRoleForMember(String orgId, UpdateRoleRequest updateR
MemberRole.fromValue(updateRoleRequest.getRole())));
}

private Mono<OrgMember> checkVisitorAdminRole(String orgId) {
@Override
public Mono<OrgMember> checkVisitorAdminRole(String orgId) {
return sessionUserService.getVisitorId()
.flatMap(visitor -> orgMemberService.getOrgMember(orgId, visitor))
.filter(it -> it.getRole() == MemberRole.ADMIN || it.getRole() == MemberRole.SUPER_ADMIN)
Expand All @@ -177,15 +178,18 @@ private Mono<Void> checkDeveloperCount(String orgId, String role, String userId)
@Override
public Mono<Boolean> switchCurrentOrganizationTo(String nextCurrentOrgId) {
return sessionUserService.getVisitorId()
.flatMap(it -> orgMemberService.getAllActiveOrgs(it).collectList())
.flatMap(it -> switchCurrentOrganizationTo(it, nextCurrentOrgId));
}

@Override
public Mono<Boolean> switchCurrentOrganizationTo(String userId, String nextCurrentOrgId) {
return orgMemberService.getAllActiveOrgs(userId).collectList()
.defaultIfEmpty(Collections.emptyList())
.flatMap(orgMembers -> {
if (!collectSet(orgMembers, OrgMember::getOrgId).contains(nextCurrentOrgId)) {
return Mono.error(new BizException(BizError.INVALID_ORG_ID, "INVALID_ORG_ID"));
}

String userId = orgMembers.get(0).getUserId();

Optional<OrgMember> previousCurrentOrgMember = orgMembers.stream()
.filter(OrgMember::isCurrentOrg)
.findFirst();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.lowcoder.api.authentication.dto.OrganizationDomainCheckResult;
import org.lowcoder.api.authentication.service.AuthenticationApiService;
import org.lowcoder.api.framework.view.ResponseView;
import org.lowcoder.api.home.SessionUserService;
import org.lowcoder.api.home.UserHomeApiService;
import org.lowcoder.api.usermanagement.view.UpdateUserRequest;
import org.lowcoder.api.usermanagement.view.UserProfileView;
import org.lowcoder.domain.organization.model.MemberRole;
import org.lowcoder.domain.organization.service.OrgMemberService;
import org.lowcoder.domain.user.constant.UserStatusType;
import org.lowcoder.domain.user.model.User;
import org.lowcoder.domain.user.model.UserDetail;
import org.lowcoder.domain.user.service.UserService;
import org.lowcoder.domain.user.service.UserStatusService;
import org.lowcoder.sdk.config.CommonConfig;
import org.lowcoder.sdk.constants.AuthSourceConstants;
import org.lowcoder.sdk.exception.BizError;
import org.springframework.http.HttpStatus;
import org.springframework.http.codec.multipart.Part;
Expand All @@ -35,6 +39,19 @@ public class UserController implements UserEndpoints
private final UserStatusService userStatusService;
private final UserApiService userApiService;
private final CommonConfig commonConfig;
private final AuthenticationApiService authenticationApiService;
private final OrgMemberService orgMemberService;

@Override
public Mono<ResponseView<?>> createUserAndAddToOrg(@PathVariable String orgId, CreateUserRequest request) {
return orgApiService.checkVisitorAdminRole(orgId).flatMap(__ ->
authenticationApiService.authenticateByForm(request.email(), request.password(),
AuthSourceConstants.EMAIL, true, null, orgId))
.flatMap(authUser -> userService.createNewUserByAuthUser(authUser, false))
.delayUntil(user -> orgMemberService.tryAddOrgMember(orgId, user.getId(), MemberRole.MEMBER))
.delayUntil(user -> orgApiService.switchCurrentOrganizationTo(user.getId(), orgId))
.map(ResponseView::success);
}

@Override
public Mono<ResponseView<?>> getUserProfile(ServerWebExchange exchange) {
Expand Down Expand Up @@ -67,19 +84,27 @@ public Mono<ResponseView<Boolean>> markStatus(@RequestBody MarkUserStatusRequest
@Override
public Mono<ResponseView<UserProfileView>> update(@RequestBody UpdateUserRequest updateUserRequest, ServerWebExchange exchange) {
return sessionUserService.getVisitorId()
.flatMap(uid -> {
User updateUser = new User();
if (StringUtils.isNotBlank(updateUserRequest.getName())) {
updateUser.setName(updateUserRequest.getName());
updateUser.setHasSetNickname(true);
}
if (StringUtils.isNotBlank(updateUserRequest.getUiLanguage())) {
updateUser.setUiLanguage(updateUserRequest.getUiLanguage());
}
return userService.update(uid, updateUser);
})
.flatMap(user -> userHomeApiService.buildUserProfileView(user, exchange))
.map(ResponseView::success);
.flatMap(uid -> updateUser(uid, updateUserRequest, exchange));
}

@Override
public Mono<ResponseView<UserProfileView>> update(@PathVariable String orgId, @PathVariable String userId, @RequestBody UpdateUserRequest updateUserRequest, ServerWebExchange exchange) {
return orgApiService.checkVisitorAdminRole(orgId)
.flatMap(__ -> updateUser(userId, updateUserRequest, exchange));
}

public Mono<ResponseView<UserProfileView>> updateUser(String userId, @RequestBody UpdateUserRequest updateUserRequest, ServerWebExchange exchange) {
User updateUser = new User();
if (StringUtils.isNotBlank(updateUserRequest.getName())) {
updateUser.setName(updateUserRequest.getName());
updateUser.setHasSetNickname(true);
}
if (StringUtils.isNotBlank(updateUserRequest.getUiLanguage())) {
updateUser.setUiLanguage(updateUserRequest.getUiLanguage());
}
return userService.update(userId, updateUser)
.flatMap(user -> userHomeApiService.buildUserProfileView(user, exchange))
.map(ResponseView::success);
}

@Override
Expand All @@ -89,13 +114,28 @@ public Mono<ResponseView<Boolean>> uploadProfilePhoto(@RequestPart("file") Mono<
.map(ResponseView::success);
}

@Override
public Mono<ResponseView<Boolean>> uploadProfilePhotoById(@PathVariable String orgId, @PathVariable String userId, @RequestPart("file") Mono<Part> fileMono) {
return orgApiService.checkVisitorAdminRole(orgId).flatMap(__ -> userService.findById(userId))
.zipWith(fileMono)
.flatMap(tuple -> userService.saveProfilePhoto(tuple.getT2(), tuple.getT1()))
.map(ResponseView::success);
}

@Override
public Mono<ResponseView<Void>> deleteProfilePhoto() {
return sessionUserService.getVisitor()
.flatMap(visitor -> userService.deleteProfilePhoto(visitor)
.map(ResponseView::success));
}

@Override
public Mono<ResponseView<Void>> deleteProfilePhotoById(@PathVariable String orgId, @PathVariable String userId) {
return orgApiService.checkVisitorAdminRole(orgId).flatMap(__ -> userService.findById(userId))
.flatMap(user -> userService.deleteProfilePhoto(user)
.map(ResponseView::success));
}

@Override
public Mono<Void> getProfilePhoto(ServerWebExchange exchange) {
return sessionUserService.getVisitorId()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,20 @@

@RestController
@RequestMapping(value = {Url.USER_URL, NewUrl.USER_URL})
public interface UserEndpoints
public interface UserEndpoints
{
public static final String TAG_USER_MANAGEMENT = "User APIs";
public static final String TAG_USER_PASSWORD_MANAGEMENT = "User Password APIs";
public static final String TAG_USER_PROFILE_PHOTO_MANAGEMENT = "User Profile Photo APIs";

@Operation(
tags = TAG_USER_MANAGEMENT,
operationId = "createUserAndAddToOrg",
summary = "Create user and add to the org",
description = "Create a new user and add to specified organization."
)
@PostMapping("/new/{orgId}")
public Mono<ResponseView<?>> createUserAndAddToOrg(@PathVariable String orgId, @RequestBody CreateUserRequest request);

@Operation(
tags = TAG_USER_MANAGEMENT,
operationId = "getUserProfile",
Expand Down Expand Up @@ -67,6 +75,15 @@ public interface UserEndpoints
@PutMapping
public Mono<ResponseView<UserProfileView>> update(@RequestBody UpdateUserRequest updateUserRequest, ServerWebExchange exchange);

@Operation(
tags = TAG_USER_MANAGEMENT,
operationId = "updateUser",
summary = "Update selected User",
description = "Update specified user profile information within Lowcoder, ensuring accuracy and relevance."
)
@PutMapping("/{orgId}/{userId}")
public Mono<ResponseView<UserProfileView>> update(@PathVariable String orgId, @PathVariable String userId, @RequestBody UpdateUserRequest updateUserRequest, ServerWebExchange exchange);

@Operation(
tags = TAG_USER_PROFILE_PHOTO_MANAGEMENT,
operationId = "uploadUserProfilePhoto",
Expand All @@ -78,12 +95,30 @@ public interface UserEndpoints

@Operation(
tags = TAG_USER_PROFILE_PHOTO_MANAGEMENT,
operationId = "deleteUserProfilePhoto",
summary = "Delete current users profile photo",
description = "Remove the profile Photo associated with the current User within Lowcoder."
operationId = "uploadUserProfilePhotoById",
summary = "Upload specific Users profile photo",
description = "Upload or change specific profile photo within Lowcoder for personalization."
)
@PostMapping(value = "/photo/{orgId}/{userId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<ResponseView<Boolean>> uploadProfilePhotoById(@PathVariable String orgId, @PathVariable String userId, @RequestPart("file") Mono<Part> fileMono);

@Operation(
tags = TAG_USER_PROFILE_PHOTO_MANAGEMENT,
operationId = "deleteUserProfilePhotoById",
summary = "Delete specific users profile photo",
description = "Remove the profile Photo associated with the specific User within Lowcoder."
)
@DeleteMapping("/photo")
public Mono<ResponseView<Void>> deleteProfilePhoto();

@DeleteMapping("/photo/{orgId}/{userId}")
public Mono<ResponseView<Void>> deleteProfilePhotoById(@PathVariable String orgId, @PathVariable String userId);
@Operation(
tags = TAG_USER_PROFILE_PHOTO_MANAGEMENT,
operationId = "deleteUserProfilePhoto",
summary = "Delete current users profile photo",
description = "Remove the profile Photo associated with the current User within Lowcoder."
)
@DeleteMapping("/photo")
public Mono<ResponseView<Void>> deleteProfilePhoto();

@Operation(
tags = TAG_USER_PROFILE_PHOTO_MANAGEMENT,
Expand Down Expand Up @@ -181,4 +216,7 @@ public record UpdatePasswordRequest(String oldPassword, String newPassword) {
public record MarkUserStatusRequest(String type, Object value) {
}

public record CreateUserRequest(String email, String password) {
}

}
Loading