package com.plannaplan.controllers; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.Date; import com.plannaplan.App; import com.plannaplan.entities.User; import com.plannaplan.models.ConfigData; import com.plannaplan.models.TourData; import com.plannaplan.responses.models.ConfigTourResponse; import com.plannaplan.security.cas.CasUserIdentity; import com.plannaplan.security.cas.CasValidationExcepiton; import com.plannaplan.security.cas.CasValidator; import com.plannaplan.security.cas.CustomUAMCasValidator; import com.plannaplan.security.cas.DefaultUAMCasValidator; import com.plannaplan.services.ConfiguratorService; import com.plannaplan.services.UserService; import com.plannaplan.types.UserRoles; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.web.bind.annotation.GetMapping; /** * Rest controller to Config related endpoints. More detailed api docs is * available via swagger */ @RestController @CrossOrigin @RequestMapping("/api/" + App.API_VERSION + "/configurator") @EnableGlobalMethodSecurity(prePostEnabled = true) @Api(tags = { "ConfigController" }, value = "ConfigController", description = "All endpoints to configure an app") public class ConfigController { @Value("${plannaplan.frontendUrl}") private String serviceUrl; @Value("${plannaplan.dev}") private boolean isDev; @Autowired private ConfiguratorService contrl; @Autowired private UserService userService; /** * @param file file .xlsx that contains courses and groups with * apoinnted rules * @param firstTourBegin formated string dd.MM.yyyy * @param firstTourEnd formated string dd.MM.yyyy * @param secondTourBegin formated string dd.MM.yyyy * @param secondTourEnd formated string dd.MM.yyyy * @return was config success */ @PostMapping(path = "/config", consumes = { "multipart/form-data" }) @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Imports data to system. To call you need to provide ADMIN token") public ResponseEntity configApp( @RequestParam("file") @ApiParam(value = "file .xlsx that contains courses and groups with apoinnted rules") MultipartFile file, @RequestParam("firstTourBegin") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when first tour begin in format dd.MM.yyyy") Date firstTourBegin, @RequestParam("firstTourEnd") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when first tour ends in format dd.MM.yyyy") Date firstTourEnd, @RequestParam("secondTourBegin") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when second tour begin in format dd.MM.yyyy") Date secondTourBegin, @RequestParam("secondTourEnd") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when second tour ends in format dd.MM.yyyy") Date secondTourEnd) { try { if (!(firstTourBegin.before(firstTourEnd) && (firstTourEnd.before(secondTourBegin) || firstTourEnd.equals(secondTourBegin)) && secondTourBegin.before(secondTourEnd))) { return new ResponseEntity<>("Bad dates", HttpStatus.BAD_REQUEST); } final TourData firstTour = new TourData(firstTourBegin, firstTourEnd); final TourData secondTour = new TourData(secondTourBegin, secondTourEnd); final ConfigData data = new ConfigData(firstTour, secondTour, file.getInputStream()); this.contrl.config(data); return new ResponseEntity<>("Sucess", HttpStatus.OK); } catch (IOException e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } /** * @param firstTourBegin formated string dd.MM.yyyy * @param firstTourEnd formated string dd.MM.yyyy * @param secondTourBegin formated string dd.MM.yyyy * @param secondTourEnd formated string dd.MM.yyyy * @return was operation successful */ @PostMapping(path = "/config/tours") @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Set tours dates. To call you need to provide ADMIN token") public ResponseEntity configToursApp( @RequestParam("firstTourBegin") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when first tour begin in format dd.MM.yyyy") Date firstTourBegin, @RequestParam("firstTourEnd") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when first tour ends in format dd.MM.yyyy") Date firstTourEnd, @RequestParam("secondTourBegin") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when second tour begin in format dd.MM.yyyy") Date secondTourBegin, @RequestParam("secondTourEnd") @DateTimeFormat(pattern = "dd.MM.yyyy") @ApiParam(value = "Date when second tour ends in format dd.MM.yyyy") Date secondTourEnd) { if (!(firstTourBegin.before(firstTourEnd) && (firstTourEnd.before(secondTourBegin) || firstTourEnd.equals(secondTourBegin)) && secondTourBegin.before(secondTourEnd))) { return new ResponseEntity<>("Bad dates", HttpStatus.BAD_REQUEST); } final TourData firstTour = new TourData(firstTourBegin, firstTourEnd); final TourData secondTour = new TourData(secondTourBegin, secondTourEnd); this.contrl.saveTours(firstTour, secondTour); return new ResponseEntity<>("Sucess", HttpStatus.OK); } /** * @param file file .xlsx that contains courses and groups with * @return was operation successfull */ @PostMapping(path = "/config/courses", consumes = { "multipart/form-data" }) @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Imports data to system. To call you need to provide ADMIN token") public ResponseEntity configAppChangeCources( @RequestParam("file") @ApiParam(value = "file .xlsx that contains courses and groups with apoinnted rules") MultipartFile file) { try { this.contrl.importCoursesStream(file.getInputStream()); return new ResponseEntity<>("Sucess", HttpStatus.OK); } catch (IOException e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } /** * @param ticket CAS ticket to get user wuthority * @return was admin created */ @PostMapping(path = "/admin/init") @ApiOperation("It can be run only in the initialization of the application. It will create admin user to manage the application.") public ResponseEntity initAdmin( @RequestParam("ticket") @ApiParam(value = "Ticket for validation.") String ticket) { if (this.userService.adminExists()) { return new ResponseEntity<>("Admin had been already created.", HttpStatus.FORBIDDEN); } final CasValidator validator = isDev ? new DefaultUAMCasValidator(serviceUrl, ticket) : new CustomUAMCasValidator(serviceUrl, ticket); try { final CasUserIdentity casUserIdentity = validator.validate(); final String usosId = casUserIdentity.getUsosId(); final String authority = casUserIdentity.getEmail(); this.userService.save(new User(null, null, authority, usosId, UserRoles.ADMIN)); return new ResponseEntity<>("Success", HttpStatus.OK); } catch (CasValidationExcepiton e) { return new ResponseEntity<>("CAS validation failed", HttpStatus.UNAUTHORIZED); } catch (Exception e) { return new ResponseEntity<>("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR); } } /** * @return api response entity */ @GetMapping(path = "/config/tour") @ApiOperation("It will return what tour is currently on.") public ResponseEntity getCurrentTourDate() { final ConfigTourResponse response = new ConfigTourResponse(this.contrl.getCurrentConfig().getCurrentState()); return new ResponseEntity<>(response, HttpStatus.OK); } /** * @return api response entity */ @Deprecated @GetMapping(path = "/admin/tour") @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("It will return what tour is currently on. You need to provide admin token. It is depreaceted use /configurator/config/tour isntead.") public ResponseEntity getTourDate() { final ConfigTourResponse response = new ConfigTourResponse(this.contrl.getCurrentConfig().getCurrentState()); return new ResponseEntity<>(response, HttpStatus.OK); } }