diff --git a/.gitignore b/.gitignore index 41c11c4..95fc025 100755 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,7 @@ build/ ### Python ### __pycache__ -.pytest_cache \ No newline at end of file +.pytest_cache + +### Parser ### +parser/ \ No newline at end of file diff --git a/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java b/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java index 5e2e095..44af1f6 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java +++ b/buisnesslogic/src/main/java/com/plannaplan/configutils/FileToDatabaseMigrator.java @@ -32,6 +32,9 @@ public class FileToDatabaseMigrator { private static final String ROOM_STRING = "sala"; private static final String CAPACITY_STRING = "Mc"; + private static final String ZAJ_CYK_ID = "zaj_cyk_id"; + private static final String GR_NR = "gr_nr"; + @Autowired private LecturerService lecturerService; @Autowired @@ -56,6 +59,9 @@ public class FileToDatabaseMigrator { int roomIndex = data.getIndexOf(FileToDatabaseMigrator.ROOM_STRING); int capacityIndex = data.getIndexOf(FileToDatabaseMigrator.CAPACITY_STRING); + int zajCykIdIndex = data.getIndexOf(FileToDatabaseMigrator.ZAJ_CYK_ID); + int grNrIndex = data.getIndexOf(FileToDatabaseMigrator.GR_NR); + while (rows.hasNext()) { Row row = rows.next(); @@ -67,6 +73,12 @@ public class FileToDatabaseMigrator { String lecturerSurname = row.getCell(surnameIndex) != null ? row.getCell(surnameIndex).toString().trim() : ""; + Integer zajCykId = row.getCell(zajCykIdIndex) != null ? (int) Double.parseDouble(row.getCell(zajCykIdIndex).toString().trim()) + : null; + + Integer grNr = row.getCell(grNrIndex) != null ? (int) Double.parseDouble(row.getCell(grNrIndex).toString().trim()) + : null; + int day = (int) Double.parseDouble(row.getCell(dayIndex).toString()); WeekDay groupDay = WeekDay.getDay(day - 1); int time = parseTimeToInt(row.getCell(timeIndex).toString()); @@ -80,8 +92,12 @@ public class FileToDatabaseMigrator { .orElseGet(() -> this.lecturerService .save(new Lecturer(lecturerTitle, lecturerName, lecturerSurname))); - this.groupService.find(time, capacity, room).orElseGet( - () -> this.groupService.save(new Groups(capacity, room, course, time, groupDay, lecturer))); + Groups group = this.groupService.find(zajCykId, grNr).orElseGet( + () -> new Groups(capacity, room, course, time, groupDay, lecturer, zajCykId, grNr)); + + group.update(capacity, room, course, time, null, groupDay, lecturer); + + this.groupService.save(group); } diff --git a/buisnesslogic/src/main/java/com/plannaplan/entities/Groups.java b/buisnesslogic/src/main/java/com/plannaplan/entities/Groups.java index 3aecce0..e26ce6a 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/entities/Groups.java +++ b/buisnesslogic/src/main/java/com/plannaplan/entities/Groups.java @@ -34,10 +34,29 @@ public class Groups { @ManyToOne @JoinColumn(name = "lecturer_id") private Lecturer lecturer; + private Integer zajCykId; + private Integer grNr; public Groups() { } + public Integer getGr_nr() { + return grNr; + } + + public void setGr_nr(Integer grNr) { + this.grNr = grNr; + } + + public Integer getZaj_cyk_id() { + return zajCykId; + } + + public void setZaj_cyk_id(Integer zajCykId) { + this.zajCykId = zajCykId; + } + + /** * Groups * @@ -60,6 +79,43 @@ public class Groups { this.type = capacity >= 50 ? GroupType.LECTURE : GroupType.CLASS; } + /** + * Groups + * + * @param capacity capacity given to the groups + * @param room room given to the groups + * @param course course given to the groups + * @param time time given to the groups + * @param endTime end time of class in minutes + * @param day day given to the groups + * @param lecturer lecturer given to the groups + * @param zajCykId number of class in the term + * @param gr_nr Number of class/course + */ + public Groups(int capacity, String room, Course course, int time, int endTime, WeekDay day, Lecturer lecturer, Integer zajCykId, Integer grNr) { + this(capacity, room, course, time, endTime, day, lecturer); + this.zajCykId = zajCykId; + this.grNr = grNr; + } + + /** + * Groups + * + * @param capacity capacity given to the groups + * @param room room given to the groups + * @param course course given to the groups + * @param time time given to the groups + * @param day day given to the groups + * @param lecturer lecturer given to the groups + * @param zajCykId number of class in the term + * @param grNr Number of class/course + */ + public Groups(int capacity, String room, Course course, int time, WeekDay day, Lecturer lecturer, Integer zajCykId, Integer grNr) { + this(capacity, room, course, time, time + DEFAULT_CLASS_TIME, day, lecturer); + this.zajCykId = zajCykId; + this.grNr = grNr; + } + /** * Create groups with default class duration * @@ -74,6 +130,47 @@ public class Groups { this(capacity, room, course, time, time + DEFAULT_CLASS_TIME, day, lecturer); } + /** + * Updates given values other that are not null + * + * @param capacity capacity given to the groups + * @param room room given to the groups + * @param course course given to the groups + * @param time time given to the groups + * @param endTime end time of class in minutes + * @param day day given to the groups + * @param lecturer lecturer given to the groups + */ + public void update(Integer capacity, String room, Course course, Integer time, Integer endTime, WeekDay day, Lecturer lecturer){ + if (capacity != null){ + this.capacity = capacity; + } + + if (room != null){ + this.room = room; + } + + if (course != null){ + this.course = course; + } + + if (time != null){ + this.time = time; + } + + if (endTime != null){ + this.endTime = endTime; + } + + if (day != null){ + this.day = day; + } + + if (lecturer != null){ + this.lecturer = lecturer; + } + } + /** * get time of class end * diff --git a/buisnesslogic/src/main/java/com/plannaplan/repositories/GroupRepository.java b/buisnesslogic/src/main/java/com/plannaplan/repositories/GroupRepository.java index 019a6ad..4d20a56 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/repositories/GroupRepository.java +++ b/buisnesslogic/src/main/java/com/plannaplan/repositories/GroupRepository.java @@ -28,6 +28,9 @@ public interface GroupRepository extends JpaRepository { @Query("FROM Groups WHERE time = ?1 AND room = ?2 AND capacity = ?3") Optional find(@Param("time") int time, @Param("room") String room, @Param("capacity") int capacity); + @Query("FROM Groups WHERE zajCykId = ?1 AND grNr = ?2") + Optional find(@Param("zajCykId") Integer zaj_cyk_id, @Param("grNr") Integer gr_nr); + @Query("FROM Groups WHERE course_id = ?1") List getByCourse(@Param("id") Long id); diff --git a/buisnesslogic/src/main/java/com/plannaplan/repositories/UserRepository.java b/buisnesslogic/src/main/java/com/plannaplan/repositories/UserRepository.java index debf7ab..cd389d7 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/repositories/UserRepository.java +++ b/buisnesslogic/src/main/java/com/plannaplan/repositories/UserRepository.java @@ -35,9 +35,12 @@ import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository { - @Query("FROM User WHERE email = ?1") + @Query("FROM User WHERE email = ?1 OR usosId = ?1") Optional getByAuthority(@Param("authority") String authority); + @Query("FROM User WHERE email = ?1") + Optional getByEmail(@Param("authority") String authority); + @Query("FROM User WHERE refreshToken = ?1") Optional getByRefreshToken(@Param("refreshToken") String refreshToken); diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/ConfiguratorService.java b/buisnesslogic/src/main/java/com/plannaplan/services/ConfiguratorService.java index 8f550f4..baa7510 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/ConfiguratorService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/ConfiguratorService.java @@ -2,11 +2,13 @@ package com.plannaplan.services; import com.plannaplan.models.ConfigData; import com.plannaplan.models.FileData; +import com.plannaplan.models.TourData; import com.plannaplan.repositories.AppConfigRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.io.InputStream; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -40,6 +42,15 @@ public class ConfiguratorService { migrator.migrate(coursesData); } + /** + * Save tours to DataBase + * @param firstTour First tour period. + * @param secondTour Second tour period. + */ + public void saveTours(TourData firstTour, TourData secondTour) { + this.configRepo.save(new AppConfig(firstTour, secondTour)); + } + /** * current config getter * @@ -62,4 +73,14 @@ public class ConfiguratorService { return repsonse.get(0); } + + /** + * + * @param inputStream This input stream contains new courses to import. + */ + public void importCoursesStream(InputStream inputStream) { + FileReader reader = new FileReader(inputStream); + FileData coursesData = reader.read(); + migrator.migrate(coursesData); + } } \ No newline at end of file diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java b/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java index 65ab5c8..c3e40ca 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/GroupService.java @@ -30,6 +30,10 @@ public class GroupService { return this.repo.find(time, room, capacity); } + public Optional find(Integer zajCykId, Integer nrGr ) { + return this.repo.find(zajCykId, nrGr); + } + public List getGroupsByCourse(Long id) { return this.repo.getByCourse(id); } diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/UserService.java b/buisnesslogic/src/main/java/com/plannaplan/services/UserService.java index 9192490..4cbc924 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/UserService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/UserService.java @@ -25,12 +25,16 @@ public class UserService { } public User checkForUser(String email, String usosId) { + return this.checkForUser(email, usosId, UserRoles.STUDENT); + } + + public User checkForUser(String email, String usosId, UserRoles roleIfNotExist) { if (usosId == null) { - Optional user = this.repo.getByAuthority(email.replace("\n", "").trim()); + Optional user = this.repo.getByEmail(email.replace("\n", "").trim()); if (user.isPresent()) { return user.get(); } else { - final User newUser = new User(null, null, email.replace("\n", "").trim(), UserRoles.STUDENT); + final User newUser = new User(null, null, email.replace("\n", "").trim(), roleIfNotExist); return this.repo.save(newUser); } } else { @@ -38,7 +42,7 @@ public class UserService { if (user.isPresent()) { return user.get(); } else { - final User newUser = new User(null, null, email.replace("\n", "").trim(), usosId, UserRoles.STUDENT); + final User newUser = new User(null, null, email.replace("\n", "").trim(), usosId, roleIfNotExist); return this.repo.save(newUser); } } @@ -60,11 +64,15 @@ public class UserService { } public User getUserByEmail(String email) throws UserNotFoundException { - return this.repo.getByAuthority(email.replace("\n", "").trim()) + return this.repo.getByEmail(email.replace("\n", "").trim()) .orElseThrow(() -> new UserNotFoundException("Cannot find user with given authority")); } + public Optional getByAuthority(String authority) { + return this.repo.getByAuthority(authority); + } + public Optional getByToken(String token) { return this.repo.getByToken(token); } @@ -85,4 +93,8 @@ public class UserService { return this.repo.getByRefreshToken(refreshToken); } + public boolean adminExists(){ + return this.repo.getAllByRole(UserRoles.ADMIN).size() > 0; + } + } \ No newline at end of file diff --git a/buisnesslogic/src/test/java/com/plannaplan/configutils/FileReaderTest.java b/buisnesslogic/src/test/java/com/plannaplan/configutils/FileReaderTest.java index e8f63d2..4a01923 100755 --- a/buisnesslogic/src/test/java/com/plannaplan/configutils/FileReaderTest.java +++ b/buisnesslogic/src/test/java/com/plannaplan/configutils/FileReaderTest.java @@ -15,7 +15,7 @@ public class FileReaderTest { final FileReader r = new FileReader(inputStream); final FileData d = r.read(); assertTrue(d.getRows().next().getCell(0).toString().equals("1.0")); - assertTrue(d.getKeys().size() == 22); + assertTrue(d.getKeys().size() == 24); assertTrue(d != null); } } \ No newline at end of file diff --git a/buisnesslogic/src/test/java/com/plannaplan/repositories/UserRepositoryTest.java b/buisnesslogic/src/test/java/com/plannaplan/repositories/UserRepositoryTest.java new file mode 100644 index 0000000..76a2c2b --- /dev/null +++ b/buisnesslogic/src/test/java/com/plannaplan/repositories/UserRepositoryTest.java @@ -0,0 +1,52 @@ +package com.plannaplan.repositories; + +import static org.junit.Assert.assertTrue; + +import java.util.Optional; + +import com.plannaplan.entities.User; +import com.plannaplan.services.UserService; +import com.plannaplan.types.UserRoles; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +@ContextConfiguration +public class UserRepositoryTest { + + @Autowired + private UserService userService; + + @Autowired + private UserRepository userRepository; + + @Test + public void shouldReturnByAuthorityWithGivenEmail(){ + final String email = "shouldReturnByAuthorityWithGivenEmail@UserRepository.Test"; + final String usosId = "45678"; + final User user = this.userService.save(new User("shouldReturnByAuthority", "WithGivenEmail", email, usosId, UserRoles.TEST_USER)); + + final Optional response = this.userRepository.getByAuthority(email); + assertTrue(response.get().getEmail().equals(email)); + assertTrue(response.get().getUsosId().equals(usosId)); + assertTrue(response.get().getId().equals(user.getId())); + } + + @Test + public void shouldReturnByAuthorityWithUsosId(){ + final String email = "shouldReturnByAuthorityWithUsosId@UserRepository.Test"; + final String usosId = "45678"; + final User user = this.userService.save(new User("shouldReturnByAuthority", "WithGivenEmail", email, usosId, UserRoles.TEST_USER)); + + final Optional response = this.userRepository.getByAuthority(usosId); + assertTrue(response.get().getEmail().equals(email)); + assertTrue(response.get().getUsosId().equals(usosId)); + assertTrue(response.get().getId().equals(user.getId())); + } +} diff --git a/buisnesslogic/src/test/java/com/plannaplan/services/ConfiguratorServiceTest.java b/buisnesslogic/src/test/java/com/plannaplan/services/ConfiguratorServiceTest.java index 0190b2c..d69754d 100755 --- a/buisnesslogic/src/test/java/com/plannaplan/services/ConfiguratorServiceTest.java +++ b/buisnesslogic/src/test/java/com/plannaplan/services/ConfiguratorServiceTest.java @@ -2,6 +2,8 @@ package com.plannaplan.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -9,9 +11,11 @@ import static org.junit.Assert.assertTrue; import java.io.InputStream; import java.sql.Date; +import java.util.Optional; import com.plannaplan.TestApplication; import com.plannaplan.entities.AppConfig; +import com.plannaplan.entities.Groups; import com.plannaplan.models.ConfigData; import com.plannaplan.models.TourData; import com.plannaplan.repositories.AppConfigRepository; @@ -24,6 +28,9 @@ import org.junit.runner.RunWith; @ContextConfiguration public class ConfiguratorServiceTest { + private final static String BEFORE_UPDATE_FILE = "ZajeciaBeforeUpdate.xlsx"; + private final static String AFTER_UPDATE_FILE = "ZajeciaAfterUpdate.xlsx"; + @Autowired private ConfiguratorService configuratorService; @@ -57,6 +64,31 @@ public class ConfiguratorServiceTest { assertTrue(courses_ammount > 0 && groups_ammount > 0 && lecturers_ammount > 0); } + @Test + @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) + public void shouldUpdatePreviousImport(){ + final InputStream inputStream = getClass().getClassLoader() + .getResourceAsStream(ConfiguratorServiceTest.BEFORE_UPDATE_FILE); + this.configuratorService.importCoursesStream(inputStream); + int groups_ammount = this.groupService.getGroupsAmmount(); + + assertTrue(groups_ammount == 2); + + final InputStream inputStream2 = getClass().getClassLoader() + .getResourceAsStream(ConfiguratorServiceTest.AFTER_UPDATE_FILE); + this.configuratorService.importCoursesStream(inputStream2); + int groups_ammount2 = this.groupService.getGroupsAmmount(); + + Optional newGroup = this.groupService.find(456458, 3); + Optional updateGroup = this.groupService.find(456457, 2); + + assertTrue(groups_ammount2 == 3); + assertTrue(newGroup.isPresent()); + assertTrue(updateGroup.get().getLecturer().getSurname().equals("Murawski")); + assertTrue(updateGroup.get().getLecturer().getName().equals("Roman")); + assertTrue(updateGroup.get().getLecturer().getTitle().equals("prof. dr hab.")); + } + @Test public void shouldRetrunNewestConfig() throws InterruptedException { final Date dateToCheck = new Date(System.currentTimeMillis()); diff --git a/buisnesslogic/src/test/java/com/plannaplan/services/UserServiceTest.java b/buisnesslogic/src/test/java/com/plannaplan/services/UserServiceTest.java index fb047e7..955e497 100755 --- a/buisnesslogic/src/test/java/com/plannaplan/services/UserServiceTest.java +++ b/buisnesslogic/src/test/java/com/plannaplan/services/UserServiceTest.java @@ -2,6 +2,8 @@ package com.plannaplan.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -100,4 +102,20 @@ public class UserServiceTest { assertTrue(user.getName() != "Tom"); } + + @Test + public void shouldReturnAdminExists() { + final String email = "shouldReturnAdminExists@UserService.test"; + this.userService.save(new User("AdminTom", "Smieszny", email, UserRoles.ADMIN)); + assertTrue(userService.adminExists()); + } + + + @Test + @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) + public void shouldReturnNotAdminExists() { + final String email = "shouldReturnNotAdminExists@UserService.test"; + this.userService.save(new User("StudentTom", "Smieszny", email, UserRoles.STUDENT)); + assertTrue(userService.adminExists() == false); + } } diff --git a/buisnesslogic/src/test/resources/Zajecia.xlsx b/buisnesslogic/src/test/resources/Zajecia.xlsx index 57c8e9c..71e0ba7 100755 Binary files a/buisnesslogic/src/test/resources/Zajecia.xlsx and b/buisnesslogic/src/test/resources/Zajecia.xlsx differ diff --git a/buisnesslogic/src/test/resources/ZajeciaAfterUpdate.xlsx b/buisnesslogic/src/test/resources/ZajeciaAfterUpdate.xlsx new file mode 100644 index 0000000..bb3d360 Binary files /dev/null and b/buisnesslogic/src/test/resources/ZajeciaAfterUpdate.xlsx differ diff --git a/buisnesslogic/src/test/resources/ZajeciaBeforeUpdate.xlsx b/buisnesslogic/src/test/resources/ZajeciaBeforeUpdate.xlsx new file mode 100644 index 0000000..15b7367 Binary files /dev/null and b/buisnesslogic/src/test/resources/ZajeciaBeforeUpdate.xlsx differ diff --git a/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java b/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java index f6fc8df..9b59955 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/ConfigController.java @@ -7,11 +7,20 @@ 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.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; @@ -33,9 +42,19 @@ import io.swagger.annotations.ApiParam; @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; + + @PostMapping(path = "/config", consumes = { "multipart/form-data" }) @PreAuthorize("hasRole('ROLE_ADMIN')") @ApiOperation("Imports data to system. To call you need to provide ADMIN token") @@ -63,4 +82,63 @@ public class ConfigController { } } + + @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); + } + + @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); + } + } + + @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); + } + } } \ No newline at end of file diff --git a/restservice/src/main/java/com/plannaplan/controllers/TokenController.java b/restservice/src/main/java/com/plannaplan/controllers/TokenController.java index d771768..18b66c8 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/TokenController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/TokenController.java @@ -62,7 +62,6 @@ public class TokenController { } catch (Exception e) { return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); } - } @GetMapping("/token/refresh") diff --git a/restservice/src/main/java/com/plannaplan/controllers/UsersController.java b/restservice/src/main/java/com/plannaplan/controllers/UsersController.java index 52900f8..7d3614a 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/UsersController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/UsersController.java @@ -1,12 +1,14 @@ package com.plannaplan.controllers; import java.util.List; +import java.util.Optional; import com.plannaplan.App; import com.plannaplan.entities.User; import com.plannaplan.responses.mappers.UserResponseMappers; import com.plannaplan.responses.models.UserResponse; import com.plannaplan.services.UserService; +import com.plannaplan.types.UserRoles; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -21,6 +23,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -51,4 +54,26 @@ public class UsersController { final List response = UserResponseMappers.mapToDefaultResponse(searches); return new ResponseEntity<>(response, HttpStatus.OK); } -} + + @PostMapping(path = "/admin") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @ApiOperation(value = "Adds new admin user.") + public ResponseEntity addAdmin(@RequestParam("authority") @ApiParam(value = "USOS ID or E-mail. If user does not exist it should be USOS ID") String authority) { + final Optional userResponse = this.userService.getByAuthority(authority); + final User user = userResponse.orElseGet(() -> new User(null, null, null, authority, UserRoles.ADMIN)); + user.setRole(UserRoles.ADMIN); + this.userService.save(user); + return new ResponseEntity<>("Success", HttpStatus.OK); + } + + @PostMapping(path = "/deanery") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @ApiOperation(value = "Adds new deanery user.") + public ResponseEntity addDeanery(@RequestParam("authority") @ApiParam(value = "USOS ID or E-mail. If user does not exist it should be USOS ID") String authority) { + final Optional userResponse = this.userService.getByAuthority(authority); + final User user = userResponse.orElseGet(() -> new User(null, null, null, authority, UserRoles.DEANERY)); + user.setRole(UserRoles.DEANERY); + this.userService.save(user); + return new ResponseEntity<>("Success", HttpStatus.OK); + } +} \ No newline at end of file diff --git a/restservice/src/main/resources/Zajecia.xlsx b/restservice/src/main/resources/Zajecia.xlsx index 57c8e9c..71e0ba7 100755 Binary files a/restservice/src/main/resources/Zajecia.xlsx and b/restservice/src/main/resources/Zajecia.xlsx differ diff --git a/restservice/src/test/java/com/plannaplan/controllers/ConfigControllerTest.java b/restservice/src/test/java/com/plannaplan/controllers/ConfigControllerTest.java index b6a2e95..44275c9 100755 --- a/restservice/src/test/java/com/plannaplan/controllers/ConfigControllerTest.java +++ b/restservice/src/test/java/com/plannaplan/controllers/ConfigControllerTest.java @@ -4,6 +4,8 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import java.io.InputStream; import java.sql.Date; @@ -14,12 +16,15 @@ import com.plannaplan.services.ConfiguratorService; import com.plannaplan.services.UserService; import com.plannaplan.types.UserRoles; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; @@ -32,6 +37,9 @@ public class ConfigControllerTest extends AbstractControllerTest { private static final String FILE_NAME = "Zajecia.xlsx"; private static final String CONFIG_ENDPOINT = "/api/v1/configurator/config"; + private static final String COURSE_ENDPOINT = "/api/v1/configurator/config/courses"; + private static final String TOURS_ENDPOINT = "/api/v1/configurator/config/tours"; + private static final String ADMIN_INIT_ENDPOINT = "/api/v1/configurator/admin/init"; private static final String FIRST_TOUR_START = "firstTourBegin"; private static final String FIRST_TOUR_END = "firstTourEnd"; private static final String SECOND_TOUR_START = "secondTourBegin"; @@ -219,4 +227,120 @@ public class ConfigControllerTest extends AbstractControllerTest { .andExpect(status().is4xxClientError()); } -} + @Test + @Ignore + @DirtiesContext(methodMode = MethodMode.BEFORE_METHOD) + public void shouldCreateAdminBecouseOfEmptyDatabase() throws Exception{ + // have no idea how to make this test independent from user that run this + final String ticket = ""; + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + mockMvc.perform(get(ADMIN_INIT_ENDPOINT).param("ticket", ticket)).andExpect(status().isOk()); + } + + @Test + public void shouldFailDueToExistingAdmin() throws Exception{ + this.service.save(new User(null, null, "shouldFailDueToExistingAdmin@ConfigController.Test", UserRoles.ADMIN)); + final String ticket = "hfewlhfjlewhipfqwehipqwef"; + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + mockMvc.perform(get(ADMIN_INIT_ENDPOINT).param("ticket", ticket)).andExpect(status().is4xxClientError()); + } + + @Test + public void shouldReturnOKAuthorizedForCourses() throws Exception { + final String mail = "shouldReturnOKAuthorizedForCourses@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.ADMIN)); + + final InputStream inputStream = getClass().getClassLoader().getResourceAsStream(FILE_NAME); + final MockMultipartFile file = new MockMultipartFile("file", inputStream); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(multipart(COURSE_ENDPOINT).file(file).header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()); + + } + + @Test + public void shouldDenyForCoursesDueToWrongRole() throws Exception { + final String mail = "shouldReturnOKAuthorizedForCourses@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.TEST_USER)); + + final InputStream inputStream = getClass().getClassLoader().getResourceAsStream(FILE_NAME); + final MockMultipartFile file = new MockMultipartFile("file", inputStream); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(multipart(COURSE_ENDPOINT).file(file).header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + + } + + @Test + public void shouldReturnOKAuthorizedForTours() throws Exception { + final String mail = "shouldReturnOKAuthorizedForTours@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.ADMIN)); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(TOURS_ENDPOINT).param(FIRST_TOUR_START, "12.12.2020") + .param(FIRST_TOUR_END, "14.12.2020").param(SECOND_TOUR_START, "16.12.2020") + .param(SECOND_TOUR_END, "20.12.2020").header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()); + } + + @Test + public void shouldFailWithWrongSecondTour() throws Exception { + final String mail = "shouldFailToursWithWrongSecondTour@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.ADMIN)); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(TOURS_ENDPOINT).param(FIRST_TOUR_START, "12.12.2020") + .param(FIRST_TOUR_END, "14.12.2020").param(SECOND_TOUR_START, "16.12.2020") + .param(SECOND_TOUR_END, "13.12.2020").header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + + } + + @Test + public void shouldFailWithWrongFirstTour() throws Exception { + final String mail = "shouldFailWithWrongFirstTour@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.ADMIN)); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(TOURS_ENDPOINT).param(FIRST_TOUR_START, "12.12.2020") + .param(FIRST_TOUR_END, "10.12.2020").param(SECOND_TOUR_START, "16.12.2020") + .param(SECOND_TOUR_END, "20.12.2020").header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + + } + + @Test + public void shouldFailWithWrongSecondTourBegin() throws Exception { + final String mail = "shouldFailWithWrongSecondTourBegin@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.ADMIN)); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(TOURS_ENDPOINT).param(FIRST_TOUR_START, "12.12.2020") + .param(FIRST_TOUR_END, "14.12.2020").param(SECOND_TOUR_START, "13.12.2020") + .param(SECOND_TOUR_END, "20.12.2020").header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + + } + + @Test + public void shouldDenyForTours() throws Exception { + final String mail = "shouldDenyForTours@ConfigController.test"; + final User usr = this.service.save(new User(null, null, mail, UserRoles.TEST_USER)); + final String token = this.service.login(usr).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(TOURS_ENDPOINT).param(FIRST_TOUR_START, "12.12.2020") + .param(FIRST_TOUR_END, "14.12.2020").param(SECOND_TOUR_START, "16.12.2020") + .param(SECOND_TOUR_END, "20.12.2020").header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + + } +} \ No newline at end of file diff --git a/restservice/src/test/java/com/plannaplan/controllers/UsersControllerTest.java b/restservice/src/test/java/com/plannaplan/controllers/UsersControllerTest.java index 6c31338..939dab6 100755 --- a/restservice/src/test/java/com/plannaplan/controllers/UsersControllerTest.java +++ b/restservice/src/test/java/com/plannaplan/controllers/UsersControllerTest.java @@ -14,9 +14,13 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.junit.Assert.assertTrue; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.Optional; + @RunWith(SpringRunner.class) @SpringBootTest @ContextConfiguration @@ -24,6 +28,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. public class UsersControllerTest extends AbstractControllerTest { private static final String SEARCH_ENDPOINT = "/api/v1/users/student/search"; private static final String ALL_USERS_ENDPOINT = "/api/v1/users/students"; + private static final String ADD_ADMIN_ENDPOINT = "/api/v1/users/admin"; + private static final String ADD_DEANERY_ENDPOINT = "/api/v1/users/deanery"; @Autowired private UserService service; @@ -87,4 +93,117 @@ public class UsersControllerTest extends AbstractControllerTest { .andExpect(status().is4xxClientError()); } + @Test + public void shouldDenyNewAdminWithWrongRole() throws Exception { + final String email = "shouldDenyNewAdminWithWrongRole@shouldDenyAllStudentsTryByStudent.test"; + final User user = this.service.save(new User(null, null, email, UserRoles.TEST_USER)); + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_ADMIN_ENDPOINT).param("authority","45611").header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + } + + @Test + public void shouldDenyNewAdminWithNoParams() throws Exception { + final String email = "shouldDenyNewAdminWithNoParams@shouldDenyAllStudentsTryByStudent.test"; + final User user = this.service.save(new User(null, null, email, UserRoles.ADMIN)); + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_ADMIN_ENDPOINT).header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + } + + @Test + public void shouldCreateNewAdmin() throws Exception { + final String email = "shouldCreateNewAdmin@shouldDenyAllStudentsTryByStudent.test"; + final String usosId = "121321"; + final User user = this.service.save(new User(null, null, email, UserRoles.ADMIN)); + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_ADMIN_ENDPOINT).param("authority",usosId).header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()); + + final Optional reponse = this.service.getByAuthority(usosId); + assertTrue(reponse.get().getUsosId().equals(usosId)); + } + + @Test + public void shouldChangeExistingUserIntoAdmin() throws Exception { + final String email = "shouldChangeExistingUserIntoAdmin@shouldDenyAllStudentsTryByStudent.test"; + final String email2 = "shouldChangeExistingUserIntoAdmin2@shouldDenyAllStudentsTryByStudent.test"; + final String usosId = "121327"; + final User user = this.service.save(new User(null, null, email, UserRoles.ADMIN)); + + this.service.save(new User(null, null, email2, usosId, UserRoles.TEST_USER)); + + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_ADMIN_ENDPOINT).param("authority",usosId).header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()); + + final Optional reponse = this.service.getByAuthority(usosId); + assertTrue(reponse.get().getUsosId().equals(usosId)); + assertTrue(reponse.get().getRole().equals(UserRoles.ADMIN)); + } + + @Test + public void shouldDenyNewDeaneryWithWrongRole() throws Exception { + final String email = "shouldDenyNewDeaneryWithWrongRole@shouldDenyAllStudentsTryByStudent.test"; + final User user = this.service.save(new User(null, null, email, UserRoles.TEST_USER)); + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_DEANERY_ENDPOINT).param("authority","45611").header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + } + + @Test + public void shouldDenyNewDeaneryWithNoParams() throws Exception { + final String email = "shouldDenyNewDeaneryWithNoParams@shouldDenyAllStudentsTryByStudent.test"; + final User user = this.service.save(new User(null, null, email, UserRoles.ADMIN)); + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_DEANERY_ENDPOINT).header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + } + + @Test + public void shouldCreateNewDeanery() throws Exception { + final String email = "shouldCreateNewDeanery@shouldDenyAllStudentsTryByStudent.test"; + final String usosId = "121322"; + final User user = this.service.save(new User(null, null, email, UserRoles.ADMIN)); + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_DEANERY_ENDPOINT).param("authority",usosId).header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()); + + final Optional reponse = this.service.getByAuthority(usosId); + assertTrue(reponse.get().getUsosId().equals(usosId)); + } + + @Test + public void shouldChangeExistingUserIntoDeanery() throws Exception { + final String email = "shouldChangeExistingUserIntoDeanery@shouldDenyAllStudentsTryByStudent.test"; + final String email2 = "shouldChangeExistingUserIntoDeanery2@shouldDenyAllStudentsTryByStudent.test"; + final String usosId = "121328"; + final User user = this.service.save(new User(null, null, email, UserRoles.ADMIN)); + + this.service.save(new User(null, null, email2, usosId, UserRoles.TEST_USER)); + + final String token = this.service.login(user).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(post(ADD_DEANERY_ENDPOINT).param("authority",usosId).header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()); + + final Optional reponse = this.service.getByAuthority(usosId); + assertTrue(reponse.get().getUsosId().equals(usosId)); + assertTrue(reponse.get().getRole().equals(UserRoles.DEANERY)); + } } diff --git a/restservice/src/test/resources/Zajecia.xlsx b/restservice/src/test/resources/Zajecia.xlsx index 57c8e9c..71e0ba7 100755 Binary files a/restservice/src/test/resources/Zajecia.xlsx and b/restservice/src/test/resources/Zajecia.xlsx differ