diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/dto/property/OrgPropertyDtos.kt b/src/main/kotlin/com/android/trisolarisserver/controller/dto/property/OrgPropertyDtos.kt index 53857a5..b93137d 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/dto/property/OrgPropertyDtos.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/dto/property/OrgPropertyDtos.kt @@ -85,6 +85,10 @@ data class PropertyUserRoleRequest( val roles: Set ) +data class PropertyUserDisableRequest( + val disabled: Boolean +) + data class PropertyUserResponse( val userId: UUID, val propertyId: UUID, diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt b/src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt index 0442024..de93fc8 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/property/Properties.kt @@ -6,6 +6,7 @@ import com.android.trisolarisserver.controller.common.requireUser import com.android.trisolarisserver.component.auth.PropertyAccess import com.android.trisolarisserver.controller.dto.property.PropertyCreateRequest import com.android.trisolarisserver.controller.dto.property.PropertyResponse +import com.android.trisolarisserver.controller.dto.property.PropertyUserDisableRequest import com.android.trisolarisserver.controller.dto.property.PropertyUpdateRequest import com.android.trisolarisserver.controller.dto.property.PropertyUserResponse import com.android.trisolarisserver.controller.dto.property.PropertyUserRoleRequest @@ -161,6 +162,55 @@ class Properties( ) } + @PutMapping("/properties/{propertyId}/users/{userId}/disabled") + fun updatePropertyUserDisabled( + @PathVariable propertyId: UUID, + @PathVariable userId: UUID, + @AuthenticationPrincipal principal: MyPrincipal?, + @RequestBody request: PropertyUserDisableRequest + ): PropertyUserResponse { + requirePrincipal(principal) + propertyAccess.requireMember(propertyId, principal!!.userId) + + val actorUser = appUserRepo.findById(principal.userId).orElse(null) + val actorRoles = propertyUserRepo.findRolesByPropertyAndUser(propertyId, principal.userId) + + val targetId = PropertyUserId(propertyId = propertyId, userId = userId) + val target = propertyUserRepo.findById(targetId).orElseThrow { + ResponseStatusException(HttpStatus.NOT_FOUND, "User not found in property") + } + val targetRoles = target.roles + + if (actorUser?.superAdmin != true) { + val canAdminManage = actorRoles.contains(Role.ADMIN) + val canManagerManage = actorRoles.contains(Role.MANAGER) + val allowedForManager = setOf( + Role.STAFF, + Role.AGENT, + Role.HOUSEKEEPING, + Role.FINANCE, + Role.GUIDE, + Role.SUPERVISOR + ) + val allowed = when { + canAdminManage -> !targetRoles.contains(Role.ADMIN) + canManagerManage -> targetRoles.all { allowedForManager.contains(it) } + else -> false + } + if (!allowed) { + throw ResponseStatusException(HttpStatus.FORBIDDEN, "Role not allowed") + } + } + + target.disabled = request.disabled + val saved = propertyUserRepo.save(target) + return PropertyUserResponse( + userId = saved.id.userId!!, + propertyId = saved.id.propertyId!!, + roles = saved.roles.map { it.name }.toSet() + ) + } + @DeleteMapping("/properties/{propertyId}/users/{userId}") @ResponseStatus(HttpStatus.NO_CONTENT) fun deletePropertyUser( diff --git a/src/main/kotlin/com/android/trisolarisserver/models/property/PropertyUser.kt b/src/main/kotlin/com/android/trisolarisserver/models/property/PropertyUser.kt index 76ed2d0..ec0e564 100644 --- a/src/main/kotlin/com/android/trisolarisserver/models/property/PropertyUser.kt +++ b/src/main/kotlin/com/android/trisolarisserver/models/property/PropertyUser.kt @@ -30,7 +30,10 @@ class PropertyUser( ] ) @Column(name = "role") - var roles: MutableSet = mutableSetOf() + var roles: MutableSet = mutableSetOf(), + + @Column(name = "is_disabled", nullable = false) + var disabled: Boolean = false ) @Embeddable