Skip to content

Commit

Permalink
[backend] Implement upsert on teams and users
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelHassine committed Apr 18, 2024
1 parent 449390a commit 3225539
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 4 deletions.
22 changes: 22 additions & 0 deletions openbas-api/src/main/java/io/openbas/migration/V2_86__Teams.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.openbas.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.Statement;

@Component
public class V2_86__Teams extends BaseJavaMigration {

@Override
public void migrate(Context context) throws Exception {
Connection connection = context.getConnection();
Statement select = connection.createStatement();
// Create table
select.execute("""
CREATE UNIQUE INDEX teams_unique on teams (team_name);
""");
}
}
26 changes: 26 additions & 0 deletions openbas-api/src/main/java/io/openbas/rest/team/TeamApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

import static io.openbas.config.SessionHelper.currentUser;
import static io.openbas.database.model.User.ROLE_USER;
Expand Down Expand Up @@ -109,6 +110,31 @@ public Team createTeam(@Valid @RequestBody TeamCreateInput input) {
return teamRepository.save(team);
}

@PostMapping("/api/teams/upsert")
@PreAuthorize("isPlanner()")
public Team upsertTeam(@Valid @RequestBody TeamCreateInput input) {
if (input.getContextual() && input.getExerciseIds().toArray().length > 1) {
throw new UnsupportedOperationException("Contextual team can only be associated to one exercise");
}
Optional<Team> team = teamRepository.findByName(input.getName());
if( team.isPresent() ) {
Team existingTeam = team.get();
existingTeam.setUpdateAttributes(input);
existingTeam.setUpdatedAt(now());
existingTeam.setTags(fromIterable(tagRepository.findAllById(input.getTagIds())));
existingTeam.setOrganization(updateRelation(input.getOrganizationId(), existingTeam.getOrganization(), organizationRepository));
return teamRepository.save(existingTeam);
} else {
Team newTeam = new Team();
newTeam.setUpdateAttributes(input);
newTeam.setOrganization(updateRelation(input.getOrganizationId(), newTeam.getOrganization(), organizationRepository));
newTeam.setTags(fromIterable(tagRepository.findAllById(input.getTagIds())));
newTeam.setExercises(fromIterable(exerciseRepository.findAllById(input.getExerciseIds())));
newTeam.setScenarios(fromIterable(scenarioRepository.findAllById(input.getScenarioIds())));
return teamRepository.save(newTeam);
}
}

@DeleteMapping("/api/teams/{teamId}")
@PreAuthorize("isPlanner()")
public void deleteTeam(@PathVariable String teamId) {
Expand Down
44 changes: 40 additions & 4 deletions openbas-api/src/main/java/io/openbas/rest/user/PlayerApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@

import io.openbas.config.OpenBASPrincipal;
import io.openbas.config.SessionManager;
import io.openbas.database.model.Communication;
import io.openbas.database.model.Inject;
import io.openbas.database.model.Organization;
import io.openbas.database.model.User;
import io.openbas.database.model.*;
import io.openbas.database.repository.*;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.rest.user.form.player.CreatePlayerInput;
import io.openbas.rest.user.form.player.UpdatePlayerInput;
import io.openbas.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import static io.openbas.config.SessionHelper.currentUser;
import static io.openbas.helper.DatabaseHelper.updateRelation;
import static io.openbas.helper.StreamHelper.fromIterable;
import static java.time.Instant.now;

@RestController
public class PlayerApi extends RestBehavior {
Expand All @@ -36,6 +37,11 @@ public class PlayerApi extends RestBehavior {
private UserRepository userRepository;
private TagRepository tagRepository;
private UserService userService;
private final TeamRepository teamRepository;

public PlayerApi(TeamRepository teamRepository) {
this.teamRepository = teamRepository;
}

@Autowired
public void setCommunicationRepository(CommunicationRepository communicationRepository) {
Expand Down Expand Up @@ -109,6 +115,36 @@ public User createPlayer(@Valid @RequestBody CreatePlayerInput input) {
return savedUser;
}

@Transactional(rollbackOn = Exception.class)
@PostMapping("/api/players/upsert")
@PreAuthorize("isPlanner()")
public User upsertPlayer(@Valid @RequestBody CreatePlayerInput input) {
checkOrganizationAccess(userRepository, input.getOrganizationId());
Optional<User> user = userRepository.findByEmailIgnoreCase(input.getEmail());
if( user.isPresent() ) {
User existingUser = user.get();
existingUser.setUpdateAttributes(input);
existingUser.setUpdatedAt(now());
Iterable<String> tags = Stream.concat(existingUser.getTags().stream().map(Tag::getId).toList().stream(), input.getTagIds().stream()).distinct().toList();
existingUser.setTags(fromIterable(tagRepository.findAllById(tags)));
Iterable<String> teams = Stream.concat(existingUser.getTeams().stream().map(Team::getId).toList().stream(), input.getTeamIds().stream()).distinct().toList();
existingUser.setTeams(fromIterable(teamRepository.findAllById(teams)));
if( StringUtils.hasText(input.getOrganizationId()) ) {
existingUser.setOrganization(updateRelation(input.getOrganizationId(), existingUser.getOrganization(), organizationRepository));
}
return userRepository.save(existingUser);
} else {
User newUser = new User();
newUser.setUpdateAttributes(input);
newUser.setTags(fromIterable(tagRepository.findAllById(input.getTagIds())));
newUser.setOrganization(updateRelation(input.getOrganizationId(), newUser.getOrganization(), organizationRepository));
newUser.setTeams(fromIterable(teamRepository.findAllById(input.getTeamIds())));
User savedUser = userRepository.save(newUser);
userService.createUserToken(savedUser);
return savedUser;
}
}

@PutMapping("/api/players/{userId}")
@PreAuthorize("isPlanner()")
public User updatePlayer(@PathVariable String userId, @Valid @RequestBody UpdatePlayerInput input) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ public class CreatePlayerInput {
@JsonProperty("user_tags")
private List<String> tagIds = new ArrayList<>();

@JsonProperty("user_teams")
private List<String> teamIds = new ArrayList<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public interface TeamRepository extends CrudRepository<Team, String>, JpaSpecifi
@NotNull
Optional<Team> findById(@NotNull String id);

Optional<Team> findByName(String name);

List<Team> findByNameIgnoreCase(String name);

@Query("select team from Team team where team.organization is null or team.organization.id in :organizationIds")
Expand Down

0 comments on commit 3225539

Please sign in to comment.