Skip to content

Commit

Permalink
Merge pull request #758 from puzzle/704_benutzerverwaltung
Browse files Browse the repository at this point in the history
704 benutzerverwaltung
  • Loading branch information
Makae authored Jan 30, 2024
2 parents 12cad92 + 0f65754 commit 930e30d
Show file tree
Hide file tree
Showing 362 changed files with 9,689 additions and 7,626 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
outputs: type=docker,dest=/tmp/okr-docker-image.tar

- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: okr-image
path: /tmp/okr-docker-image.tar
Expand All @@ -76,7 +76,7 @@ jobs:
uses: actions/checkout@v4

- name: Download artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: okr-image
path: /tmp
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/staging-deploy-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
outputs: type=docker,dest=/tmp/okr-docker-image.tar

- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: okr-image
path: /tmp/okr-docker-image.tar
Expand All @@ -99,7 +99,7 @@ jobs:
- uses: actions/checkout@v4

- name: Download artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: okr-image
path: /tmp
Expand Down Expand Up @@ -158,7 +158,7 @@ jobs:
- uses: actions/checkout@v4

- name: Download artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: okr-image
path: /tmp
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ sonar-project.properties
/frontend/cypress/downloads/
/frontend/cypress/screenshots/
/toolchains.xml
/backend/src/main/resources/db/okr_schema.sql
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This project contains two parts:

[Frontend description](frontend/README.md)


## Backend
[Backend description](backend/README.md)

Expand Down
16 changes: 8 additions & 8 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<parent>
<groupId>ch.puzzle.okr</groupId>
<artifactId>parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.39-SNAPSHOT</version>
</parent>

<artifactId>backend</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.39-SNAPSHOT</version>
<name>backend</name>
<description>Puzzle OKR Tool</description>

Expand Down Expand Up @@ -59,12 +59,12 @@
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>10.1.0</version>
<version>10.6.0</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
<version>10.2.0</version>
<version>10.6.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
Expand All @@ -84,7 +84,7 @@
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.24.2</version>
<version>3.25.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand All @@ -93,7 +93,7 @@
<plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
<version>2.7.10</version>
<version>2.7.11</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -208,7 +208,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.2.2</version>
<version>3.2.5</version>
<configuration>
<excludes></excludes>
</configuration>
Expand All @@ -224,7 +224,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.2</version>
<version>3.2.5</version>
</plugin>

<plugin>
Expand Down
2 changes: 2 additions & 0 deletions backend/src/main/java/ch/puzzle/okr/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ private Constants() {
public static final String KEY_RESULT_TYPE_METRIC = "metric";
public static final String KEY_RESULT_TYPE_ORDINAL = "ordinal";
public static final String OBJECTIVE = "Objective";
public static final String STATE_DRAFT = "Draft";
public static final String KEY_RESULT = "KeyResult";
public static final String CHECK_IN = "Check-in";
public static final String ACTION = "Action";
Expand All @@ -16,4 +17,5 @@ private Constants() {
public static final String QUARTER = "Quarter";
public static final String TEAM = "Team";
public static final String USER = "User";
public static final String USER_TEAM = "UserTeam";
}
5 changes: 3 additions & 2 deletions backend/src/main/java/ch/puzzle/okr/ErrorKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public enum ErrorKey {
ATTRIBUTE_NULL, ATTRIBUTE_CHANGED, ATTRIBUTE_SET_FORBIDDEN, ATTRIBUTE_NOT_SET, ATTRIBUTE_CANNOT_CHANGE,
KEY_RESULT_CONVERSION, ALREADY_EXISTS_SAME_NAME, CONVERT_TOKEN, DATA_HAS_BEEN_UPDATED, MODEL_NULL,
MODEL_WITH_ID_NOT_FOUND, NOT_AUTHORIZED_TO_READ, NOT_AUTHORIZED_TO_WRITE, NOT_AUTHORIZED_TO_DELETE, TOKEN_NULL
ATTRIBUTE_MUST_BE_DRAFT, KEY_RESULT_CONVERSION, ALREADY_EXISTS_SAME_NAME, CONVERT_TOKEN, DATA_HAS_BEEN_UPDATED,
MODEL_NULL, MODEL_WITH_ID_NOT_FOUND, NOT_AUTHORIZED_TO_READ, NOT_AUTHORIZED_TO_WRITE, NOT_AUTHORIZED_TO_DELETE,
TOKEN_NULL
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public class SpringCachingConfig {

@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(AUTHORIZATION_USER_CACHE, USER_CACHE);
return new ConcurrentMapCacheManager(AUTHORIZATION_USER_CACHE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,6 @@ public void emptyAuthorizationUsersCache() {
cacheService.emptyAuthorizationUsersCache();
}

@Operation(summary = "Delete users cache", description = "Delete users cache")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Users cache deleted") })
@PostMapping("emptyUsersCache")
public void emptyUsersCache() {
cacheService.emptyUsersCache();
}

@Operation(summary = "Delete all caches", description = "Delete all caches")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "All caches deleted") })
@PostMapping("emptyAllCaches")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package ch.puzzle.okr.controller;

import ch.puzzle.okr.dto.overview.DashboardDto;
import ch.puzzle.okr.dto.overview.OverviewDto;
import ch.puzzle.okr.mapper.DashboardMapper;
import ch.puzzle.okr.mapper.OverviewMapper;
import ch.puzzle.okr.service.authorization.OverviewAuthorizationService;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -23,14 +21,12 @@
@RequestMapping("api/v2/overview")
public class OverviewController {
private final OverviewMapper overviewMapper;
private final DashboardMapper dashboardMapper;
private final OverviewAuthorizationService overviewAuthorizationService;

public OverviewController(OverviewMapper overviewMapper, OverviewAuthorizationService overviewAuthorizationService,
DashboardMapper dashboardMapper) {
public OverviewController(OverviewMapper overviewMapper,
OverviewAuthorizationService overviewAuthorizationService) {
this.overviewMapper = overviewMapper;
this.overviewAuthorizationService = overviewAuthorizationService;
this.dashboardMapper = dashboardMapper;
}

@Operation(summary = "Get all teams and their objectives", description = "Get a List of teams with their objectives")
Expand All @@ -41,14 +37,11 @@ public OverviewController(OverviewMapper overviewMapper, OverviewAuthorizationSe
@ApiResponse(responseCode = "401", description = "Not authorized to read teams with their objectives", content = @Content),
@ApiResponse(responseCode = "404", description = "The quarter or one of the teams were not found", content = @Content) })
@GetMapping("")
public ResponseEntity<DashboardDto> getOverview(
public ResponseEntity<List<OverviewDto>> getOverview(
@RequestParam(required = false, defaultValue = "", name = "team") List<Long> teamFilter,
@RequestParam(required = false, defaultValue = "", name = "quarter") Long quarterFilter,
@RequestParam(required = false, defaultValue = "", name = "objectiveQuery") String objectiveQuery) {
boolean hasWriteAllAccess = overviewAuthorizationService.hasWriteAllAccess();
return ResponseEntity.status(HttpStatus.OK)
.body(dashboardMapper.toDto(overviewMapper.toDto(
overviewAuthorizationService.getFilteredOverview(quarterFilter, teamFilter, objectiveQuery)),
hasWriteAllAccess));
return ResponseEntity.status(HttpStatus.OK).body(overviewMapper
.toDto(overviewAuthorizationService.getFilteredOverview(quarterFilter, teamFilter, objectiveQuery)));
}
}
45 changes: 40 additions & 5 deletions backend/src/main/java/ch/puzzle/okr/controller/TeamController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.puzzle.okr.controller;

import ch.puzzle.okr.dto.TeamDto;
import ch.puzzle.okr.dto.UserDto;
import ch.puzzle.okr.mapper.TeamMapper;
import ch.puzzle.okr.models.Team;
import ch.puzzle.okr.service.authorization.TeamAuthorizationService;
Expand Down Expand Up @@ -34,9 +35,7 @@ public TeamController(TeamAuthorizationService teamAuthorizationService, TeamMap
@Content(mediaType = "application/json", schema = @Schema(implementation = TeamDto.class)) }), })
@GetMapping
public List<TeamDto> getAllTeams() {
List<Long> userTeamIds = teamAuthorizationService.getUserTeamIds();
return teamAuthorizationService.getAllTeams().stream().map(team -> teamMapper.toDto(team, userTeamIds))
.toList();
return teamAuthorizationService.getAllTeams().stream().map(teamMapper::toDto).toList();
}

@Operation(summary = "Create Team", description = "Create a new Team")
Expand All @@ -49,7 +48,7 @@ public List<TeamDto> getAllTeams() {
public ResponseEntity<TeamDto> createTeam(
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "The Team as json to create a new Team.", required = true) @RequestBody TeamDto teamDto) {
Team createdTeam = teamAuthorizationService.createEntity(teamMapper.toTeam(teamDto));
return ResponseEntity.status(HttpStatus.CREATED).body(teamMapper.toDto(createdTeam, List.of()));
return ResponseEntity.status(HttpStatus.CREATED).body(teamMapper.toDto(createdTeam));
}

@Operation(summary = "Update Team", description = "Update a Team by ID.")
Expand All @@ -64,7 +63,7 @@ public ResponseEntity<TeamDto> updateTeam(
@Parameter(description = "The ID for updating a Team.", required = true) @PathVariable long id,
@RequestBody TeamDto teamDto) {
Team updatedTeam = teamAuthorizationService.updateEntity(teamMapper.toTeam(teamDto), id);
return ResponseEntity.status(OK).body(teamMapper.toDto(updatedTeam, List.of()));
return ResponseEntity.status(OK).body(teamMapper.toDto(updatedTeam));
}

@Operation(summary = "Delete Team by ID", description = "Delete Team by ID")
Expand All @@ -76,4 +75,40 @@ public void deleteTeamById(
@Parameter(description = "The ID of an Team to delete it.", required = true) @PathVariable long id) {
teamAuthorizationService.deleteEntity(id);
}

@Operation(summary = "Add users to a team", description = "Add users to a team")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Added users to team"),
@ApiResponse(responseCode = "401", description = "Not authorized to add users to the team", content = @Content),
@ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
@PutMapping("/{id}/addusers")
public void addUsersToTeam(
@Parameter(description = "The ID of an Team to add to users to it.", required = true) @PathVariable long id,
@RequestBody List<UserDto> userDtoList) {
var userIds = userDtoList.stream().map(UserDto::id).toList();
teamAuthorizationService.addUsersToTeam(id, userIds);
}

@Operation(summary = "Remove User from Team", description = "Remove User with given UserID from Team")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Removed User from Team"),
@ApiResponse(responseCode = "401", description = "Not authorized to remove user from team", content = @Content),
@ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
@PutMapping("/{id}/user/{userId}/removeuser")
public void removeUserFromTeam(
@Parameter(description = "The ID of an team to remove the user from it.", required = true) @PathVariable long id,
@Parameter(description = "The User ID to remove from the team.", required = true) @PathVariable long userId) {
teamAuthorizationService.removeUserFromTeam(id, userId);
}

@Operation(summary = "Update or add team membership", description = "If user is already member of this team, isAdmin is set. otherwise new team membership "
+ "is added with isAdmin true or false")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Update or add team membership"),
@ApiResponse(responseCode = "401", description = "Not authorized to update or add team membership", content = @Content),
@ApiResponse(responseCode = "404", description = "Did not find the Team with requested ID") })
@PutMapping("/{id}/user/{userId}/updateaddteammembership/{isAdmin}")
public void updateOrAddTeamMembership(
@Parameter(description = "The ID of an team to update or add membership", required = true) @PathVariable long id,
@Parameter(description = "The User ID to update or add membership", required = true) @PathVariable long userId,
@Parameter(description = "The parameter if user should be admin or not", required = true) @PathVariable boolean isAdmin) {
teamAuthorizationService.updateOrAddTeamMembership(id, userId, isAdmin);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import ch.puzzle.okr.dto.UserDto;
import ch.puzzle.okr.mapper.UserMapper;
import ch.puzzle.okr.service.authorization.AuthorizationService;
import ch.puzzle.okr.service.authorization.UserAuthorizationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -19,10 +22,13 @@
public class UserController {

private final UserAuthorizationService userAuthorizationService;
private final AuthorizationService authorizationService;
private final UserMapper userMapper;

public UserController(UserAuthorizationService userAuthorizationService, UserMapper userMapper) {
public UserController(UserAuthorizationService userAuthorizationService, AuthorizationService authorizationService,
UserMapper userMapper) {
this.userAuthorizationService = userAuthorizationService;
this.authorizationService = authorizationService;
this.userMapper = userMapper;
}

Expand All @@ -34,4 +40,24 @@ public List<UserDto> getAllUsers() {
return userAuthorizationService.getAllUsers().stream().map(userMapper::toDto).toList();
}

@Operation(summary = "Get Current User", description = "Get all current logged in user.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Returned current logged in user.", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
@GetMapping(path = "/current")
public UserDto getCurrentUser() {
var currentUser = this.authorizationService.updateOrAddAuthorizationUser().user();
return userMapper.toDto(currentUser);
}

@Operation(summary = "Get User by ID", description = "Get user by given ID.")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned user", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
@GetMapping(path = "/{id}")
public UserDto getUserById(
@Parameter(description = "The ID for requested user.", required = true) @PathVariable long id) {
var user = this.userAuthorizationService.getById(id);
return userMapper.toDto(user);
}

}
Loading

0 comments on commit 930e30d

Please sign in to comment.