Skip to content
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,7 +6,9 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import jakarta.annotation.PostConstruct;

import cat.udl.eps.softarch.demo.domain.Admin;
import cat.udl.eps.softarch.demo.domain.Creator;
import cat.udl.eps.softarch.demo.domain.Profile;
import java.time.ZonedDateTime;
import java.util.Arrays;

Expand All @@ -27,33 +29,62 @@ public DBInitialization(UserRepository userRepository, RecordRepository recordRe
}

@PostConstruct
public void initializeDatabase() {
// Default user
if (!userRepository.existsById("demo")) {
public void initializeDatabase() {


if (!userRepository.existsById("demo")) {
User user = new User();
user.setEmail("demo@sample.app");
user.setId("demo");
user.setPassword(defaultPassword);
user.encodePassword();
userRepository.save(user);
}

if (!userRepository.existsById("admin")) {
Admin admin = new Admin();
admin.setEmail("admin@sample.app");
admin.setId("admin");
admin.setPassword(defaultPassword);
admin.encodePassword();
userRepository.save(admin);
}

if (!userRepository.existsById("creator")) {
Creator creator = new Creator();
creator.setEmail("seed-creator@sample.app");
creator.setId("creator");
creator.setPassword(defaultPassword);
creator.encodePassword();
creator.setEnabled(true);
Profile profile = new Profile();
profile.setDescription("");
profile.setVisibility(Profile.Visibility.PRIVATE);
creator.setProfile(profile);
userRepository.save(creator);
}

// ======================
// 🧪 TEST DATA (tu lógica)
// ======================
if (Arrays.asList(activeProfiles.split(",")).contains("test")) {

if (!userRepository.existsById("test")) {
User user = new User();
user.setEmail("demo@sample.app");
user.setId("demo");
user.setEmail("test@sample.app");
user.setId("test");
user.setPassword(defaultPassword);
user.encodePassword();
userRepository.save(user);
}
if (Arrays.asList(activeProfiles.split(",")).contains("test")) {
// Testing instances
if (!userRepository.existsById("test")) {
User user = new User();
user.setEmail("test@sample.app");
user.setId("test");
user.setPassword(defaultPassword);
user.encodePassword();
user = userRepository.save(user);
cat.udl.eps.softarch.demo.domain.Record record = new Record();
record.setName("My test record");
record.setDescription("A record used for testing purposes, nothing more, nothing less...");
record.setCreated(ZonedDateTime.now());
record.setModified(record.getCreated());
record.setOwnedBy(user);
recordRepository.save(record);
}
user = userRepository.save(user);

Record record = new Record();
record.setName("My test record");
record.setDescription("A record used for testing purposes...");
record.setCreated(ZonedDateTime.now());
record.setModified(record.getCreated());
record.setOwnedBy(user);
recordRepository.save(record);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cat.udl.eps.softarch.demo.config;

import java.util.List;
import java.util.Map;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class RestApiExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, List<Map<String, String>>>> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex) {
List<Map<String, String>> errors = ex.getBindingResult().getFieldErrors().stream()
.map(fe -> Map.of("message", fe.getDefaultMessage() != null ? fe.getDefaultMessage() : ""))
.toList();
return ResponseEntity.badRequest().body(Map.of("errors", errors));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exce
.requestMatchers(HttpMethod.GET, "/admins/{username}").hasRole("ADMIN")
.requestMatchers(HttpMethod.POST, "/admins/*/suspend").hasRole("ADMIN")
.requestMatchers(HttpMethod.POST, "/admins/*").denyAll()
// Creators
.requestMatchers(HttpMethod.GET, "/creators").permitAll()
.requestMatchers(HttpMethod.POST, "/creators").permitAll()
//Creators
.requestMatchers(HttpMethod.GET, "/creators").hasRole("ADMIN")
.requestMatchers(HttpMethod.POST, "/creators").permitAll()
.requestMatchers(HttpMethod.GET, "/creators/{username}").permitAll()
.requestMatchers(HttpMethod.PUT, "/creators/{username}").hasRole("ADMIN")
.requestMatchers(HttpMethod.PUT, "/creators/*/profile").authenticated()
.requestMatchers(HttpMethod.POST, "/creators/*").hasRole("ADMIN")

// Projects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,31 @@

import cat.udl.eps.softarch.demo.domain.Creator;
import cat.udl.eps.softarch.demo.repository.CreatorRepository;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import cat.udl.eps.softarch.demo.domain.Profile;
import org.springframework.web.bind.annotation.RestController;
import jakarta.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import org.springframework.hateoas.CollectionModel;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;

@RepositoryRestController

@RestController
public class CustomCreatorController {

private CreatorRepository creatorRepository;
public CustomCreatorController(CreatorRepository creatorRepository){
this.creatorRepository = creatorRepository;
}

// PUT creators/username
@PutMapping("/creators/{username}/profile")
@PreAuthorize("@CreatorSecurity.isOwner(principal.username, #username)")
public ResponseEntity<Creator> updateCreator(@PathVariable String username,
@RequestBody Creator updated) {

Creator creator = creatorRepository.findById(username)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));

if (updated.getProfile() != null) {
creator.setProfile(updated.getProfile());
}
if(updated.getEmail() !=null){
creator.setEmail(updated.getEmail());
}

creatorRepository.save(creator);
return ResponseEntity.ok(creator);
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/creators/{username}/suspend")
public ResponseEntity<Creator> suspendCreator (@PathVariable String username) {
Expand All @@ -46,8 +37,83 @@ public ResponseEntity<Creator> suspendCreator (@PathVariable String username) {
creatorRepository.save(creator);

return ResponseEntity.ok(creator);


}

@PostMapping("/creators")
public ResponseEntity<Creator> createCreator(@Valid @RequestBody Creator creator) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && !(auth instanceof AnonymousAuthenticationToken)) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
}
if (creator.getUsername() != null && creatorRepository.existsById(creator.getUsername())) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "Username already exists");
}
if (creator.getEmail() != null && creatorRepository.countByEmail(creator.getEmail()) > 0) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "Email already registered");
}
creator.encodePassword();
Profile profile = new Profile();
profile.setDescription("");
profile.setVisibility(Profile.Visibility.PRIVATE);

creator.setProfile(profile);

Creator saved = creatorRepository.save(creator);

return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}

@GetMapping("/me/profile")
@PreAuthorize("hasRole('CREATOR')")
public Profile getMyProfile(Authentication auth) {

Creator creator = creatorRepository.findById(auth.getName())
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));

return creator.getProfile();
}

@GetMapping("/creators")
@PreAuthorize("hasRole('ADMIN')")
public CollectionModel<Creator> getCreators() {

List<Creator> creators = new ArrayList<>();
creatorRepository.findAll().forEach(creators::add);

return CollectionModel.of(creators,
linkTo(methodOn(CustomCreatorController.class).getCreators()).withSelfRel()
);
}

@PutMapping("/me/profile")
@PreAuthorize("hasRole('CREATOR')")
public Profile updateMyProfile(@RequestBody Profile updated, Authentication auth) {
return updateProfileForCreator(auth.getName(), updated);
}

@PutMapping("/creators/{username}/profile")
@PreAuthorize("hasRole('CREATOR') and authentication.name.equals(#username)")
public Profile updateCreatorProfile(@PathVariable String username, @RequestBody Profile updated) {
return updateProfileForCreator(username, updated);
}

private Profile updateProfileForCreator(String username, Profile updated) {
Creator creator = creatorRepository.findById(username)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));

Profile profile = creator.getProfile();

if (profile == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}

profile.setDescription(updated.getDescription());
profile.setVisibility(updated.getVisibility());

creatorRepository.save(creator);

return profile;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ResponseStatusException;

import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RepositoryRestController("customProfileController")
@RestController
public class CustomProfileController {

private final ProfileRepository profileRepository;
Expand All @@ -25,7 +25,7 @@ public CustomProfileController(ProfileRepository profileRepository) {
}

// PUT /profiles/id
@PutMapping("/products/{id}")
@PutMapping("/profiles/{id}")
@PreAuthorize("@profileSecurity.isOwner(principal.username, #id)")
@ResponseBody
public ResponseEntity<Profile> updateProfile(@PathVariable Long id,
Expand All @@ -45,7 +45,7 @@ public ResponseEntity<Profile> updateProfile(@PathVariable Long id,
return ResponseEntity.ok(profile);
}

@GetMapping("/products/{id}")
@GetMapping("/profiles/{id}")
@PreAuthorize("@profileSecurity.isOwner(principal.username, #id) or @profileSecurity.isPublic(#id)")
@ResponseBody
public ResponseEntity<Profile> getProfile(@PathVariable Long id) {
Expand All @@ -55,7 +55,7 @@ public ResponseEntity<Profile> getProfile(@PathVariable Long id) {
}


@GetMapping("/products/")
@GetMapping("/profiles/")
@ResponseBody
public ResponseEntity<List<Profile>> getPublicProfiles() {
List<Profile> publicProfiles = ((List<Profile>) profileRepository.findAll())
Expand All @@ -64,4 +64,5 @@ public ResponseEntity<List<Profile>> getPublicProfiles() {
.toList();
return ResponseEntity.ok(publicProfiles);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,4 @@ public void thereIsStillOnlyOneCreatorWithUsername(String username) {
}
assertEquals(1, count, "There should still be only one creator with username \"" + username + "\"");
}
}
}