fix: null safety in role/group creation, add user create/update endpoints
- RoleAdminController.createRole: default null description to "" and null scope to "custom"
- RoleAdminController.updateRole: pass null audit details to avoid NPE when name is null
- GroupAdminController.updateGroup: pass null audit details to avoid NPE when name is null
- UserAdminController: add POST / createUser endpoint with default VIEWER role assignment
- UserAdminController: add PUT /{userId} updateUser endpoint for displayName/email updates
This commit is contained in:
@@ -111,7 +111,7 @@ public class GroupAdminController {
|
|||||||
|
|
||||||
groupRepository.update(id, request.name(), request.parentGroupId());
|
groupRepository.update(id, request.name(), request.parentGroupId());
|
||||||
auditService.log("update_group", AuditCategory.RBAC, id.toString(),
|
auditService.log("update_group", AuditCategory.RBAC, id.toString(),
|
||||||
Map.of("name", request.name()), AuditResult.SUCCESS, httpRequest);
|
null, AuditResult.SUCCESS, httpRequest);
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,9 @@ public class RoleAdminController {
|
|||||||
@ApiResponse(responseCode = "200", description = "Role created")
|
@ApiResponse(responseCode = "200", description = "Role created")
|
||||||
public ResponseEntity<Map<String, UUID>> createRole(@RequestBody CreateRoleRequest request,
|
public ResponseEntity<Map<String, UUID>> createRole(@RequestBody CreateRoleRequest request,
|
||||||
HttpServletRequest httpRequest) {
|
HttpServletRequest httpRequest) {
|
||||||
UUID id = roleRepository.create(request.name(), request.description(), request.scope());
|
String desc = request.description() != null ? request.description() : "";
|
||||||
|
String sc = request.scope() != null ? request.scope() : "custom";
|
||||||
|
UUID id = roleRepository.create(request.name(), desc, sc);
|
||||||
auditService.log("create_role", AuditCategory.RBAC, id.toString(),
|
auditService.log("create_role", AuditCategory.RBAC, id.toString(),
|
||||||
Map.of("name", request.name()), AuditResult.SUCCESS, httpRequest);
|
Map.of("name", request.name()), AuditResult.SUCCESS, httpRequest);
|
||||||
return ResponseEntity.ok(Map.of("id", id));
|
return ResponseEntity.ok(Map.of("id", id));
|
||||||
@@ -93,7 +95,7 @@ public class RoleAdminController {
|
|||||||
}
|
}
|
||||||
roleRepository.update(id, request.name(), request.description(), request.scope());
|
roleRepository.update(id, request.name(), request.description(), request.scope());
|
||||||
auditService.log("update_role", AuditCategory.RBAC, id.toString(),
|
auditService.log("update_role", AuditCategory.RBAC, id.toString(),
|
||||||
Map.of("name", request.name()), AuditResult.SUCCESS, httpRequest);
|
null, AuditResult.SUCCESS, httpRequest);
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import com.cameleer3.server.core.admin.AuditCategory;
|
|||||||
import com.cameleer3.server.core.admin.AuditResult;
|
import com.cameleer3.server.core.admin.AuditResult;
|
||||||
import com.cameleer3.server.core.admin.AuditService;
|
import com.cameleer3.server.core.admin.AuditService;
|
||||||
import com.cameleer3.server.core.rbac.RbacService;
|
import com.cameleer3.server.core.rbac.RbacService;
|
||||||
|
import com.cameleer3.server.core.rbac.SystemRole;
|
||||||
import com.cameleer3.server.core.rbac.UserDetail;
|
import com.cameleer3.server.core.rbac.UserDetail;
|
||||||
|
import com.cameleer3.server.core.security.UserInfo;
|
||||||
import com.cameleer3.server.core.security.UserRepository;
|
import com.cameleer3.server.core.security.UserRepository;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
@@ -16,9 +18,12 @@ import org.springframework.web.bind.annotation.DeleteMapping;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -63,6 +68,43 @@ public class UserAdminController {
|
|||||||
return ResponseEntity.ok(detail);
|
return ResponseEntity.ok(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Operation(summary = "Create a local user")
|
||||||
|
@ApiResponse(responseCode = "200", description = "User created")
|
||||||
|
public ResponseEntity<UserDetail> createUser(@RequestBody CreateUserRequest request,
|
||||||
|
HttpServletRequest httpRequest) {
|
||||||
|
String userId = "user:" + request.username();
|
||||||
|
UserInfo user = new UserInfo(userId, "local",
|
||||||
|
request.email() != null ? request.email() : "",
|
||||||
|
request.displayName() != null ? request.displayName() : request.username(),
|
||||||
|
Instant.now());
|
||||||
|
userRepository.upsert(user);
|
||||||
|
rbacService.assignRoleToUser(userId, SystemRole.VIEWER_ID);
|
||||||
|
auditService.log("create_user", AuditCategory.USER_MGMT, userId,
|
||||||
|
Map.of("username", request.username()), AuditResult.SUCCESS, httpRequest);
|
||||||
|
return ResponseEntity.ok(rbacService.getUser(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{userId}")
|
||||||
|
@Operation(summary = "Update user display name or email")
|
||||||
|
@ApiResponse(responseCode = "200", description = "User updated")
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
public ResponseEntity<Void> updateUser(@PathVariable String userId,
|
||||||
|
@RequestBody UpdateUserRequest request,
|
||||||
|
HttpServletRequest httpRequest) {
|
||||||
|
var existing = userRepository.findById(userId);
|
||||||
|
if (existing.isEmpty()) return ResponseEntity.notFound().build();
|
||||||
|
var user = existing.get();
|
||||||
|
var updated = new UserInfo(user.userId(), user.provider(),
|
||||||
|
request.email() != null ? request.email() : user.email(),
|
||||||
|
request.displayName() != null ? request.displayName() : user.displayName(),
|
||||||
|
user.createdAt());
|
||||||
|
userRepository.upsert(updated);
|
||||||
|
auditService.log("update_user", AuditCategory.USER_MGMT, userId,
|
||||||
|
null, AuditResult.SUCCESS, httpRequest);
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/{userId}/roles/{roleId}")
|
@PostMapping("/{userId}/roles/{roleId}")
|
||||||
@Operation(summary = "Assign a role to a user")
|
@Operation(summary = "Assign a role to a user")
|
||||||
@ApiResponse(responseCode = "200", description = "Role assigned")
|
@ApiResponse(responseCode = "200", description = "Role assigned")
|
||||||
@@ -122,4 +164,7 @@ public class UserAdminController {
|
|||||||
null, AuditResult.SUCCESS, httpRequest);
|
null, AuditResult.SUCCESS, httpRequest);
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record CreateUserRequest(String username, String displayName, String email) {}
|
||||||
|
public record UpdateUserRequest(String displayName, String email) {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user