33 Commits

Author SHA1 Message Date
165dee5bd2 Updated gitlab-ci
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
2020-12-23 12:56:37 +01:00
76cf5c8e96 Merge pull request 'refresh-token' (#35) from refresh-token into master
Accepted
Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/35
2020-12-23 12:41:03 +01:00
6eac8e6266 Added tests 2020-12-23 12:12:50 +01:00
61c5a43192 Added refresh token endpoint 2020-12-23 11:51:17 +01:00
7f630ccdac email date update 2020-12-21 17:58:11 +01:00
64447b61c8 email date update 2020-12-21 17:48:27 +01:00
7584f3600f email date update 2020-12-21 17:34:03 +01:00
e18f285dd6 Merge pull request 'email' (#34) from email into master
Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/34
2020-12-21 17:11:32 +01:00
28c09bea6e Added event service 2020-12-21 17:12:10 +01:00
a294ecac37 Servcice mail 2020-12-20 16:44:30 +01:00
0d6ad184bc Merge pull request 'timeto-owner' (#33) from timeto-owner into master
Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/33
2020-12-20 15:15:03 +01:00
dfae6d7c78 Added info about commiter to comision entity 2020-12-20 13:04:25 +01:00
c62674b9d8 Added time to in group resonse 2020-12-20 12:14:12 +01:00
8dc94f84c0 user response fix 2020-12-18 17:43:03 +01:00
48c23ad4f8 Merge pull request 'user-fix' (#32) from user-fix into master
Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/32
2020-12-18 17:28:02 +01:00
b93d44346c new endpoint testd 2020-12-18 17:23:41 +01:00
4a12dceab6 logs 2020-12-18 16:33:58 +01:00
ce0d63d7f9 Added docs 2020-12-18 15:52:05 +01:00
300130af7e Checnging endpoints added needs docs 2020-12-18 15:49:46 +01:00
5ef7c19ade user nules 2020-12-18 15:24:01 +01:00
ca440a3fd5 Merge pull request 'turs' (#31) from turs into master
Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/31
2020-12-14 15:50:35 +01:00
ffc4f4709b Merged with master 2020-12-12 15:38:47 +01:00
84d7ed8e65 Added method to getting app states 2020-12-12 15:33:00 +01:00
e02523b4f4 Added current config getter 2020-12-12 13:33:11 +01:00
5a1108e1bf Added getting newest config 2020-12-11 18:08:23 +01:00
15533525af Database timezone fixed 2020-12-11 16:18:43 +01:00
d2a679fb22 added dev conig 2020-12-11 15:27:38 +01:00
0b807e355c chckpoint: test to buisnesslogic/src/test/java/com/plannaplan/repositories/AppConfigRepositoryTest.java 2020-12-09 17:43:48 +01:00
062b02da6c user docs corrected 2020-12-09 16:57:49 +01:00
0cee454356 Added saving conifg to databse 2020-12-09 16:43:29 +01:00
f08e7cf1e5 Swagger doscs 2020-12-09 15:10:19 +01:00
7c0c22e790 Added required parameters to config 2020-12-09 15:02:06 +01:00
b1091cd3bc Added tour data model 2020-12-08 18:16:17 +01:00
43 changed files with 1192 additions and 189 deletions

View File

@ -17,6 +17,8 @@ build:
expire_in: 1 hour expire_in: 1 hour
paths: paths:
- restservice/target/ - restservice/target/
only:
- master
deploy_production: deploy_production:
stage: deploy stage: deploy

View File

@ -35,21 +35,23 @@ spring.profiles.active=prod
Jeżeli chcemy zmienić jakieś opcję dla pordukcji to robimy to w tym sammym katalogi w pliku `application-prod.properties` i dla dev analogicznie w `application-dev.properties`. Jeżeli chcemy zmienić jakieś opcję dla pordukcji to robimy to w tym sammym katalogi w pliku `application-prod.properties` i dla dev analogicznie w `application-dev.properties`.
W paczce dla proda w protpertiesach poufne dane odczytywane są ze zmiennych środowiskowych systemu na którym odpalana jest aplikacja. Ustawić trzeba następujące zmienne: W paczce dla proda w protpertiesach poufne dane odczytywane są ze zmiennych środowiskowych systemu na którym odpalana jest aplikacja. Ustawić trzeba następujące zmienne:
- PLANNAPLAN_MYSQL_DB_HOST - host bazy danych np `localhost` - `PLANNAPLAN_MYSQL_DB_HOST` - host bazy danych np `localhost`
- PLANNAPLAN_MYSQL_DB_PORT - port na którym działa baza - `PLANNAPLAN_MYSQL_DB_PORT` - port na którym działa baza
- PLANNAPLAN_MYSQL_DB - nazwa bazy dancyh. W profilu **dev** jest to np test - `PLANNAPLAN_MYSQL_DB` - nazwa bazy dancyh. W profilu **dev** jest to np test
- PLANNAPLAN_MYSQL_DB_USERNAME - nazwa użytkownika bazy - `PLANNAPLAN_MYSQL_DB_USERNAME` - nazwa użytkownika bazy
- PLANNAPLAN_MYSQL_DB_PASSWORD - hasło użytkownika bazy - `PLANNAPLAN_MYSQL_DB_PASSWORD` - hasło użytkownika bazy
- `PLANNAPLAN_EMAIL_HOST` - host naszego dostawcy maila z którego będziemy wssyłać wiadomości
- `PLANNAPLAN_EMAIL_PORT` - port naszego dostawcy maila
- `PLANNAPLAN_EMAIL_USERNAME` - login naszego maila
- `PLANNAPLAN_EMAIL_PASSWORD` - hasło naszego maila
- `PLANNAPLAN_EMAIL` - nasz adres maila
## Packaging ## Packaging
Zeby spakowac apke do `jara` wystarcza dwie komendy zaczynajac z glownego katalogu projektu Zeby spakowac apke do `jara` wystarcza dwie komendy zaczynajac z glownego katalogu projektu
``` ```
mvn clean mvn clean; mvn install; cd restservice; mvn clean package spring-boot:repackage
mvn install
cd restservice
mvn clean package spring-boot:repackage
``` ```
Utworzony zostanie jar w `restservice/target/restservice-1.0-SNAPSHOT.jar`. Oczywiscie zeby jar zadzialal kontenery dockerowe musza byc odpalone (lub baza danych na serwerze jesli zmienialismy propertisy z localhost) Utworzony zostanie jar w `restservice/target/restservice-1.0-SNAPSHOT.jar`. Oczywiscie zeby jar zadzialal kontenery dockerowe musza byc odpalone (lub baza danych na serwerze jesli zmienialismy propertisy z localhost)

View File

@ -68,6 +68,12 @@
<version>3.17</version> <version>3.17</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -85,14 +91,14 @@
<version>3.0.2</version> <version>3.0.2</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version> <version>3.0.0</version>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version> <version>3.8.0</version>

View File

@ -0,0 +1,9 @@
{
"properties": [
{
"name": "plannaplan.email",
"type": "java.lang.String",
"description": "Email from which app sends message"
}
]
}

View File

@ -0,0 +1,118 @@
package com.plannaplan.entities;
import java.sql.Date;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import com.plannaplan.models.TourData;
import com.plannaplan.types.AppState;
/**
* entity that keeps app configurations
*/
@Entity
public class AppConfig {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Date firstTourStart;
private Date firstTourEnd;
private Date secondTourStart;
private Date secondTourEnd;
private Timestamp configDate;
/**
* no parameter construcotor
*/
public AppConfig() {
}
/**
* constructor
*
* @param firstTour first TourData instacne
* @param scondTour second TourData instacne
*/
public AppConfig(TourData firstTour, TourData scondTour) {
this.firstTourStart = firstTour.getStart();
this.firstTourEnd = firstTour.getEnd();
this.secondTourStart = scondTour.getStart();
this.secondTourEnd = scondTour.getEnd();
this.configDate = new Timestamp(System.currentTimeMillis());
}
/**
*
* second tour end getter
*
* @return Date inforamtion when second tour ends
*/
public Date getSecondTourEnd() {
return secondTourEnd;
}
/**
* first second start getter
*
* @return Date inforamtion when second tour start
*/
public Date getSecondTourStart() {
return secondTourStart;
}
/**
* first tour end getter
*
* @return Date inforamtion when first tour end
*/
public Date getFirstTourEnd() {
return firstTourEnd;
}
/**
* first tour start getter
*
* @return Date inforamtion when first tour start
*/
public Date getFirstTourStart() {
return firstTourStart;
}
/**
* config date getter
*
* @return Timestamp when configuration took place
*/
public Timestamp getConfigDate() {
return configDate;
}
/**
* current state getter
*
* @return AppState of app at the moment of calling method
*/
public AppState getCurrentState() {
final Date now = new Date(System.currentTimeMillis());
if (this.secondTourEnd.before(now)) {
return AppState.NO_TOUR;
}
if (this.secondTourStart.before(now)) {
return AppState.SECOND_TOUR;
}
if (this.firstTourEnd.before(now)) {
return AppState.NO_TOUR;
}
if (this.firstTourStart.before(now)) {
return AppState.FIRST_TOUR;
}
return AppState.NO_TOUR;
}
}

View File

@ -13,7 +13,7 @@ import javax.persistence.OneToMany;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
/** /**
* Entity of Commision grouping of state associated about commison and owner_id * Entity of Commision grouping of state associated about commison and owner_id
*/ */
@Entity @Entity
@ -24,6 +24,9 @@ public class Commision {
@OneToOne @OneToOne
@JoinColumn(name = "owner_id") @JoinColumn(name = "owner_id")
private User commisionOwner; private User commisionOwner;
@OneToOne
@JoinColumn(name = "commiter_id")
private User commisionCommiter;
private Timestamp commisionDate; private Timestamp commisionDate;
@OneToMany(mappedBy = "commision", fetch = FetchType.EAGER) @OneToMany(mappedBy = "commision", fetch = FetchType.EAGER)
@ -37,37 +40,62 @@ public class Commision {
public Commision(User user) { public Commision(User user) {
this.commisionDate = new Timestamp(System.currentTimeMillis()); this.commisionDate = new Timestamp(System.currentTimeMillis());
this.commisionOwner = user; this.commisionOwner = user;
this.commisionCommiter = user;
}
/**
*
* @param user user whose shedule is being commited
* @param commiter user that commited new schedule
*/
public Commision(User user, User commiter) {
this(user);
this.commisionCommiter = commiter;
} }
public Commision() { public Commision() {
} }
/** /**
* Id getter * Id getter
* @return id id of commision *
* @return id id of commision
*/ */
public Long getId() { public Long getId() {
return this.id; return this.id;
} }
/** /**
* CommisionDate getter * CommisionDate getter
* @return commisionDate *
* @return commisionDate
*/ */
public Timestamp getCommisionDate() { public Timestamp getCommisionDate() {
return commisionDate; return commisionDate;
} }
/** /**
* User of given commision getter * User of given commision getter
* @return User commisionOwner *
* @return User commisionOwner
*/ */
public User getCommisionOwner() { public User getCommisionOwner() {
return commisionOwner; return commisionOwner;
} }
/**
* @return User entity that created commision (can be owner or deanery user)
*/
public User getCommisionCommiter() {
if (commisionCommiter == null) {
return commisionOwner;
}
return commisionCommiter;
}
/** /**
* Assigments getter * Assigments getter
*
* @return List of assignments * @return List of assignments
*/ */
public List<Assignment> getAssignments() { public List<Assignment> getAssignments() {

View File

@ -11,11 +11,14 @@ import com.plannaplan.types.GroupType;
import com.plannaplan.types.WeekDay; import com.plannaplan.types.WeekDay;
/** /**
* Entity of Groups grouping of state ssociated about course,time,room,capacity,type,day * Entity of Groups grouping of state ssociated about
* course,time,room,capacity,type,day
*/ */
@Entity @Entity
public class Groups { public class Groups {
private static final int DEFAULT_CLASS_TIME = 90;
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
private Long id; private Long id;
@ -23,6 +26,7 @@ public class Groups {
@JoinColumn(name = "course_id") @JoinColumn(name = "course_id")
private Course course; private Course course;
private int time; private int time;
private int endTime;
private String room; private String room;
private int capacity; private int capacity;
private GroupType type; private GroupType type;
@ -38,24 +42,50 @@ public class Groups {
* Groups * Groups
* *
* @param capacity capacity given to the groups * @param capacity capacity given to the groups
* @param room room given to the groups * @param room room given to the groups
* @param course course given to the groups * @param course course given to the groups
* @param time time given to the groups * @param time time given to the groups
* @param day day 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 lecturer lecturer given to the groups
*/ */
public Groups(int capacity, String room, Course course, int time, WeekDay day, Lecturer lecturer) { public Groups(int capacity, String room, Course course, int time, int endTime, WeekDay day, Lecturer lecturer) {
this.capacity = capacity; this.capacity = capacity;
this.room = room; this.room = room;
this.course = course; this.course = course;
this.time = time; this.time = time;
this.endTime = endTime;
this.day = day; this.day = day;
this.lecturer = lecturer; this.lecturer = lecturer;
this.type = capacity >= 50 ? GroupType.LECTURE : GroupType.CLASS; this.type = capacity >= 50 ? GroupType.LECTURE : GroupType.CLASS;
} }
/**
* Create groups with default class duration
*
* @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
*/
public Groups(int capacity, String room, Course course, int time, WeekDay day, Lecturer lecturer) {
this(capacity, room, course, time, time + DEFAULT_CLASS_TIME, day, lecturer);
}
/**
* get time of class end
*
* @return hour of class finish time in minutes
*/
public int getEndTime() {
return endTime;
}
/** /**
* getId * getId
*
* @return id * @return id
*/ */
public Long getId() { public Long getId() {
@ -64,6 +94,7 @@ public class Groups {
/** /**
* getLecturer * getLecturer
*
* @return lecturer * @return lecturer
*/ */
public Lecturer getLecturer() { public Lecturer getLecturer() {
@ -72,6 +103,7 @@ public class Groups {
/** /**
* setLecturer * setLecturer
*
* @param lecturer set lecturer into groups * @param lecturer set lecturer into groups
*/ */
public void setLecturer(Lecturer lecturer) { public void setLecturer(Lecturer lecturer) {
@ -80,6 +112,7 @@ public class Groups {
/** /**
* WeekDay * WeekDay
*
* @return day * @return day
*/ */
public WeekDay getDay() { public WeekDay getDay() {
@ -88,6 +121,7 @@ public class Groups {
/** /**
* setLecturer * setLecturer
*
* @param day set day into groups * @param day set day into groups
*/ */
public void setDay(WeekDay day) { public void setDay(WeekDay day) {
@ -96,6 +130,7 @@ public class Groups {
/** /**
* GroupType * GroupType
*
* @return type * @return type
*/ */
public GroupType getType() { public GroupType getType() {
@ -104,6 +139,7 @@ public class Groups {
/** /**
* setType * setType
*
* @param type set type into groups * @param type set type into groups
*/ */
public void setType(GroupType type) { public void setType(GroupType type) {
@ -112,6 +148,7 @@ public class Groups {
/** /**
* getCapacity * getCapacity
*
* @return capacity * @return capacity
*/ */
public int getCapacity() { public int getCapacity() {
@ -120,6 +157,7 @@ public class Groups {
/** /**
* setCapacity * setCapacity
*
* @param capacity set capacity into groups * @param capacity set capacity into groups
*/ */
public void setCapacity(int capacity) { public void setCapacity(int capacity) {
@ -128,6 +166,7 @@ public class Groups {
/** /**
* getRoom * getRoom
*
* @return room * @return room
*/ */
public String getRoom() { public String getRoom() {
@ -136,6 +175,7 @@ public class Groups {
/** /**
* setRoom * setRoom
*
* @param room set room into groups * @param room set room into groups
*/ */
public void setRoom(String room) { public void setRoom(String room) {
@ -144,6 +184,7 @@ public class Groups {
/** /**
* getTime * getTime
*
* @return time * @return time
*/ */
public int getTime() { public int getTime() {
@ -152,6 +193,7 @@ public class Groups {
/** /**
* setTime * setTime
*
* @param time set time into groups * @param time set time into groups
*/ */
public void setTime(int time) { public void setTime(int time) {
@ -160,6 +202,7 @@ public class Groups {
/** /**
* getCourseId * getCourseId
*
* @return course * @return course
*/ */
public Course getCourseId() { public Course getCourseId() {
@ -168,6 +211,7 @@ public class Groups {
/** /**
* setCourseId * setCourseId
*
* @param courseId set courseId into groups * @param courseId set courseId into groups
*/ */
public void setCourseId(Course courseId) { public void setCourseId(Course courseId) {
@ -176,6 +220,7 @@ public class Groups {
/** /**
* getTimeString * getTimeString
*
* @return time as formated String * @return time as formated String
*/ */
public String getTimeString() { public String getTimeString() {
@ -187,4 +232,19 @@ public class Groups {
} }
return String.format("%s.%s", hoursString, minutesString); return String.format("%s.%s", hoursString, minutesString);
} }
/**
* gets end time formated strins
*
* @return end time as formated String
*/
public String getEndTimeString() {
int minutes = this.getEndTime() % 60;
String hoursString = Integer.toString(this.getEndTime() / 60);
String minutesString = Integer.toString(minutes);
if (minutes < 10) {
minutesString = "0" + minutesString;
}
return String.format("%s.%s", hoursString, minutesString);
}
} }

View File

@ -1,6 +1,7 @@
package com.plannaplan.entities; package com.plannaplan.entities;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -11,7 +12,8 @@ import javax.persistence.Id;
import com.plannaplan.types.UserRoles; import com.plannaplan.types.UserRoles;
/** /**
* Entity of User grouping of state ssociated about id,name,surname,email,role,token,tokenCreatedDate * Entity of User grouping of state ssociated about
* id,name,surname,email,role,token,tokenCreatedDate
*/ */
@Entity @Entity
@ -27,19 +29,18 @@ public class User {
private String usosId; private String usosId;
private UserRoles role; private UserRoles role;
private String token; private String token;
private String refreshToken;
private Timestamp tokenUsageDate; private Timestamp tokenUsageDate;
public User() { public User() {
} }
/* /**
* User *
* * @param name name given to the user
* @param name name given to the user
* @param surname surname given to the user * @param surname surname given to the user
* @param email mail given to the user * @param mail mail given to the user
* @param role role given to the user * @param role
*/ */
public User(String name, String surname, String mail, UserRoles role) { public User(String name, String surname, String mail, UserRoles role) {
this.name = name; this.name = name;
@ -48,136 +49,152 @@ public class User {
this.role = role; this.role = role;
} }
/* /**
* User *
* * @param name name given to the user
* @param name name given to the user
* @param surname surname given to the user * @param surname surname given to the user
* @param email mail given to the user * @param mail mail given to the user
* @param usosId id in the USOS system * @param usosId id in the USOS system
* @param role role given to the user * @param role
*/ */
public User(String name, String surname, String mail, String usosId, UserRoles role){ public User(String name, String surname, String mail, String usosId, UserRoles role) {
this(name,surname,mail,role); this(name, surname, mail, role);
this.usosId = usosId; this.usosId = usosId;
} }
/* /**
* getusosId * usos id getter
* *
* @return usosId * @return usosid
*/ */
public String getUsosId() { public String getUsosId() {
return usosId; return usosId;
} }
/* /**
* getEmail * email getter
* *
* @return email * @return mailof user
*/ */
public String getEmail() { public String getEmail() {
return email; return email;
} }
/* /**
* setEmail * email setter
* *
* @param email set email to the user * @param email user email
*/ */
public void setEmail(String email) { public void setEmail(String email) {
this.email = email; this.email = email;
} }
/* /**
* getTokenUsageDate * token usage getter
* *
* @return tokenUsageDate * @return Timestamp when token was used
*/ */
public Timestamp getTokenUsageDate() { public Timestamp getTokenUsageDate() {
return tokenUsageDate; return tokenUsageDate;
} }
/* /**
* getToken * token getter
* *
* @return token * @return user token
*/ */
public String getToken() { public String getToken() {
return token; return token;
} }
/* /**
* setToken * @return token needed to call refresh token after it expired
* */
* @param token set token to the entity public String getRefreshToken() {
return refreshToken;
}
/**
* token seter. Sets token and automaticly set time when was set
*
* @param token token to set
*/ */
public void setToken(String token) { public void setToken(String token) {
this.tokenUsageDate = new Timestamp(System.currentTimeMillis()); this.tokenUsageDate = new Timestamp(System.currentTimeMillis());
this.token = token; this.token = token;
this.refreshToken = UUID.randomUUID().toString();
} }
/* getName /**
* * name setter
* @return name *
* @return String user name
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/* getRole /**
* * user rolse getter
* @return role *
* @return UserRoles of user
*/ */
public UserRoles getRole() { public UserRoles getRole() {
return role; return role;
} }
/* setRole /**
* * user role setter
* @param role set role to the entity *
* @param role to be set
*/ */
public void setRole(UserRoles role) { public void setRole(UserRoles role) {
this.role = role; this.role = role;
} }
/* /**
* getSurname * surname getter
* @return surname *
* @return string surname
*/ */
public String getSurname() { public String getSurname() {
return surname; return surname;
} }
/* /**
* setSurname * surname setter
* @param surname set surname into entity user *
* @param surname string to be set as surnames
*/ */
public void setSurname(String surname) { public void setSurname(String surname) {
this.surname = surname; this.surname = surname;
} }
/* /**
* setName * name stter
* @param name set name into entity user *
* @param name stirng to be set as name
*/ */
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
/* /**
* getId * id getter
* @return id *
* @return id in database
*/ */
public Long getId() { public Long getId() {
return this.id; return this.id;
} }
/* /**
* isCredentialsNonExpired * it checks if given ammount of time passed since last token usage. If not
* Returns TRUE if is Credentials Non Expired in the otherwise it returns false * retunr true and reset time otherwise return false and token won work anymore
*
* @return boolena if credentials (token) is expired or not
*/ */
public boolean isCredentialsNonExpired() { public boolean isCredentialsNonExpired() {
final long diffInMilliseconds = Math final long diffInMilliseconds = Math
.abs(this.tokenUsageDate.getTime() - new Timestamp(System.currentTimeMillis()).getTime()); .abs(this.tokenUsageDate.getTime() - new Timestamp(System.currentTimeMillis()).getTime());
final long minutes = TimeUnit.MILLISECONDS.toMinutes(diffInMilliseconds); final long minutes = TimeUnit.MILLISECONDS.toMinutes(diffInMilliseconds);

View File

@ -1,51 +1,50 @@
package com.plannaplan.models; package com.plannaplan.models;
import java.util.Date;
import java.io.InputStream; import java.io.InputStream;
public class ConfigData { public class ConfigData {
private Date start; private TourData firstTour;
private Date end; private TourData secondTour;
private InputStream filestream; private InputStream filestream;
/* /**
* ConfigData * constructor
* *
* @param start when the configdata begins * @param firstTour date of first tours
* @param end when the configdata ends * @param secondTour date of second tours
* @param filestream where the filestream is * @param filestream filestram with data to import
*/ */
public ConfigData(Date start, Date end, InputStream filestream) { public ConfigData(TourData firstTour, TourData secondTour, InputStream filestream) {
this.start = start; this.firstTour = firstTour;
this.end = end; this.secondTour = secondTour;
this.filestream = filestream; this.filestream = filestream;
} }
/* /**
* getFilestream * second tour getter
* *
* @return filestream * @return TourData second tour
*/
public TourData getSecondTour() {
return secondTour;
}
/**
* first tour getter
*
* @return TourData first tour
*/
public TourData getFirstTour() {
return firstTour;
}
/**
* filestream getter
*
* @return InputStream with data to import
*/ */
public InputStream getFilestream() { public InputStream getFilestream() {
return filestream; return filestream;
} }
/*
* getEnd
*
* @return end
*/
public Date getEnd() {
return end;
}
/*
* getStart
*
* @return start
*/
public Date getStart() {
return start;
}
} }

View File

@ -0,0 +1,49 @@
package com.plannaplan.models;
import java.sql.Date;
public class TourData {
private Date start;
private Date end;
/**
* construcotr for java.sql.Date
*
* @param start Date when tour start
* @param end Date when tour end
*/
public TourData(Date start, Date end) {
this.start = start;
this.end = end;
}
/**
* constructor construcotr for java.util.Date
*
* @param start Date when tour start
* @param end Date when tour end
*/
public TourData(java.util.Date start, java.util.Date end) {
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
}
/**
* tour end getter
*
* @return Date end of tour
*/
public Date getEnd() {
return end;
}
/**
* tour start getter
*
* @return Date beginning of tour
*/
public Date getStart() {
return start;
}
}

View File

@ -0,0 +1,8 @@
package com.plannaplan.repositories;
import com.plannaplan.entities.AppConfig;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AppConfigRepository extends JpaRepository<AppConfig, Long> {
}

View File

@ -12,29 +12,25 @@ import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
* UserRepository.getByAuthority: * UserRepository.getByAuthority: Return list of: SELECT * FROM User WHERE email
* Return list of: * = i.
* SELECT * FROM User WHERE email = i.
* *
* Where i, ?1 are equale to variables. * Where i, ?1 are equale to variables.
* *
* UserRepository.getByToken: * UserRepository.getByToken: Return list of: SELECT * FROM User WHERE token =
* Return list of: * i.
* SELECT * FROM User WHERE token = i.
* *
* Where i, ?1 are equale to variables. * Where i, ?1 are equale to variables.
* *
* UserRepository.searchForUsers: * UserRepository.searchForUsers: Return list of: SELECT * FROM User WHERE (name
* Return list of: * LIKE %?1% OR surname LIKE %?1%).
* SELECT * FROM User WHERE (name LIKE %?1% OR surname LIKE %?1%).
* *
* Where i, ?1 are equale to variables. * Where i, ?1 are equale to variables.
* *
* UserRepository.searchForUsers with role: * UserRepository.searchForUsers with role: Return list of: SELECT * FROM User
* Return list of: * WHERE (name LIKE %?1% OR surname LIKE %?1%) AND role=?2").
* SELECT * FROM User WHERE (name LIKE %?1% OR surname LIKE %?1%) AND role=?2").
* *
* Where i, ?1 are equale to variables. * Where i, ?1 are equale to variables.
*/ */
@Repository @Repository
@ -42,6 +38,9 @@ public interface UserRepository extends JpaRepository<User, Long> {
@Query("FROM User WHERE email = ?1") @Query("FROM User WHERE email = ?1")
Optional<User> getByAuthority(@Param("authority") String authority); Optional<User> getByAuthority(@Param("authority") String authority);
@Query("FROM User WHERE refreshToken = ?1")
Optional<User> getByRefreshToken(@Param("refreshToken") String refreshToken);
@Query("FROM User WHERE token = ?1") @Query("FROM User WHERE token = ?1")
Optional<User> getByToken(@Param("token") String token); Optional<User> getByToken(@Param("token") String token);
@ -51,6 +50,9 @@ public interface UserRepository extends JpaRepository<User, Long> {
@Query("FROM User WHERE (name LIKE %?1% OR surname LIKE %?1%) AND role=?2") @Query("FROM User WHERE (name LIKE %?1% OR surname LIKE %?1%) AND role=?2")
List<User> searchForUsers(@Param("query") String query, @Param("role") UserRoles role); List<User> searchForUsers(@Param("query") String query, @Param("role") UserRoles role);
@Query("FROM User WHERE role=?1")
List<User> getAllByRole(@Param("role") UserRoles role);
@Query("FROM User WHERE usosId = ?1") @Query("FROM User WHERE usosId = ?1")
Optional<User> getByUsosId(@Param("usosId") String usosId); Optional<User> getByUsosId(@Param("usosId") String usosId);
} }

View File

@ -2,28 +2,64 @@ package com.plannaplan.services;
import com.plannaplan.models.ConfigData; import com.plannaplan.models.ConfigData;
import com.plannaplan.models.FileData; import com.plannaplan.models.FileData;
import com.plannaplan.repositories.AppConfigRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import com.plannaplan.configutils.*; import com.plannaplan.configutils.*;
import com.plannaplan.entities.AppConfig;
/** /**
* FileReader is used for reading xls file from input stream. * FileReader is used for reading xls file from input stream.
*/ */
@Component @Component
public class ConfiguratorService { public class ConfiguratorService {
@Autowired @Autowired
private FileToDatabaseMigrator migrator; private FileToDatabaseMigrator migrator;
@Autowired
private AppConfigRepository configRepo;
public ConfiguratorService() { public ConfiguratorService() {
} }
/**
* methoid to config system
*
* @param data ConfigData containng system configs
*/
public void config(ConfigData data) { public void config(ConfigData data) {
FileReader reader = new FileReader(data.getFilestream()); FileReader reader = new FileReader(data.getFilestream());
FileData coursesData = reader.read(); FileData coursesData = reader.read();
this.configRepo.save(new AppConfig(data.getFirstTour(), data.getSecondTour()));
migrator.migrate(coursesData); migrator.migrate(coursesData);
} }
/**
* current config getter
*
* @return AppConfig with newest config_date
*/
public AppConfig getCurrentConfig() {
final List<AppConfig> repsonse = this.configRepo.findAll().stream().sorted(new Comparator<AppConfig>() {
@Override
public int compare(AppConfig i1, AppConfig i2) {
if (i1.getConfigDate().after(i2.getConfigDate())) {
return -1;
}
if (i1.getConfigDate().before(i2.getConfigDate())) {
return 1;
}
return 0;
}
}).collect(Collectors.toList());
return repsonse.get(0);
}
} }

View File

@ -0,0 +1,38 @@
package com.plannaplan.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
/**
* Service to send emails
*/
@Service
public class EmailService {
@Autowired
private JavaMailSender emailSender;
@Value("${plannaplan.email}")
private String appEmail;
public EmailService() {
}
/**
* send simple text email
*
* @param destination destitnaion mail
* @param message text to be send
*/
public void sendMail(String destination, String message) {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom(appEmail);
mailMessage.setTo(destination);
mailMessage.setSubject("[Plan na plan] INFO");
mailMessage.setText(message);
emailSender.send(mailMessage);
}
}

View File

@ -0,0 +1,17 @@
package com.plannaplan.services;
// import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class EventService {
// @Autowired
// private EmailService emailService;
@Scheduled(cron = "0 2 17 * * *")
public void collectGroupLosses() {
System.out.println("Checking for groups");
}
}

View File

@ -77,4 +77,12 @@ public class UserService {
return this.repo.findById(userId); return this.repo.findById(userId);
} }
public List<User> getAllStudents() {
return this.repo.getAllByRole(UserRoles.STUDENT);
}
public Optional<User> getUserByRefreshToken(String refreshToken) {
return this.repo.getByRefreshToken(refreshToken);
}
} }

View File

@ -0,0 +1,5 @@
package com.plannaplan.types;
public enum AppState {
FIRST_TOUR, SECOND_TOUR, NO_TOUR
}

View File

@ -0,0 +1,141 @@
package com.plannaplan.entities;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.sql.Date;
import com.plannaplan.models.TourData;
import com.plannaplan.types.AppState;
import org.junit.Test;
public class AppConfigTest {
private static long ONE_DAY = 86400000;
@Test
public void shouldReturnNoTourDueToTooEarly() {
final Date firtstTourStart = new Date(System.currentTimeMillis() + ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() + 2 * ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() + 3 * ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
assertTrue(config.getCurrentState() == AppState.NO_TOUR);
}
@Test
public void shouldReturnFirstTourDueToStart() throws InterruptedException {
final Date firtstTourStart = new Date(System.currentTimeMillis());
final Date firtstTourEnd = new Date(System.currentTimeMillis() + 2 * ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() + 3 * ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
Thread.sleep(1000);
assertTrue(config.getCurrentState() == AppState.FIRST_TOUR);
}
@Test
public void shouldReturnFirstTourDueToInBetween() {
final Date firtstTourStart = new Date(System.currentTimeMillis() - ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() + 2 * ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() + 3 * ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
assertTrue(config.getCurrentState() == AppState.FIRST_TOUR);
}
@Test
public void shouldReturnNoTourInLastDay() throws InterruptedException {
final Date firtstTourStart = new Date(System.currentTimeMillis() - ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis());
final Date secondTourStart = new Date(System.currentTimeMillis() + 3 * ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
Thread.sleep(1000);
assertTrue(config.getCurrentState() == AppState.NO_TOUR);
}
@Test
public void shouldReturnNoTourInBetween() {
final Date firtstTourStart = new Date(System.currentTimeMillis() - 2 * ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() - ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() + 3 * ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
assertTrue(config.getCurrentState() == AppState.NO_TOUR);
}
@Test
public void shouldReturnSecondTourInStart() throws InterruptedException {
final Date firtstTourStart = new Date(System.currentTimeMillis() - 2 * ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() - ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis());
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
Thread.sleep(1000);
assertTrue(config.getCurrentState() == AppState.SECOND_TOUR);
}
@Test
public void shouldReturnSecondTourInBetween() {
final Date firtstTourStart = new Date(System.currentTimeMillis() - 3 * ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() - 2 * ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() - ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() + 4 * ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
assertTrue(config.getCurrentState() == AppState.SECOND_TOUR);
}
@Test
public void shouldReturnNoTourDueToEndSecond() throws InterruptedException {
final Date firtstTourStart = new Date(System.currentTimeMillis() - 3 * ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() - 2 * ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() - ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis());
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
Thread.sleep(1000);
assertTrue(config.getCurrentState() == AppState.NO_TOUR);
}
@Test
public void shouldReturnNoTourAfterSecondEnd() {
final Date firtstTourStart = new Date(System.currentTimeMillis() - 4 * ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis() - 3 * ONE_DAY);
final Date secondTourStart = new Date(System.currentTimeMillis() - 2 * ONE_DAY);
final Date secondTourEnd = new Date(System.currentTimeMillis() - ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
assertTrue(config.getCurrentState() == AppState.NO_TOUR);
}
@Test
public void shouldReturnSecondTourWhereThereIsABrake() throws InterruptedException {
final Date firtstTourStart = new Date(System.currentTimeMillis() - 4 * ONE_DAY);
final Date firtstTourEnd = new Date(System.currentTimeMillis());
final Date secondTourStart = new Date(System.currentTimeMillis());
final Date secondTourEnd = new Date(System.currentTimeMillis() + ONE_DAY);
final AppConfig config = new AppConfig(new TourData(firtstTourStart, firtstTourEnd),
new TourData(secondTourStart, secondTourEnd));
Thread.sleep(1000);
assertTrue(config.getCurrentState() == AppState.SECOND_TOUR);
}
}

View File

@ -8,9 +8,13 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.InputStream; import java.io.InputStream;
import java.sql.Date;
import com.plannaplan.TestApplication; import com.plannaplan.TestApplication;
import com.plannaplan.entities.AppConfig;
import com.plannaplan.models.ConfigData; import com.plannaplan.models.ConfigData;
import com.plannaplan.models.TourData;
import com.plannaplan.repositories.AppConfigRepository;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -32,11 +36,18 @@ public class ConfiguratorServiceTest {
@Autowired @Autowired
private LecturerService lecturerService; private LecturerService lecturerService;
@Autowired
private AppConfigRepository appConfigRepo;
@Test @Test
public void shouldImportDataToDataBase() { public void shouldImportDataToDataBase() {
final InputStream inputStream = getClass().getClassLoader() final InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream(TestApplication.TEST_CONFIG_FILE); .getResourceAsStream(TestApplication.TEST_CONFIG_FILE);
final ConfigData data = new ConfigData(null, null, inputStream); final ConfigData data = new ConfigData(
new TourData(new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + 86400000)),
new TourData(new Date(System.currentTimeMillis() + 86400000),
new Date(System.currentTimeMillis() + 2 * 86400000)),
inputStream);
this.configuratorService.config(data); this.configuratorService.config(data);
int courses_ammount = this.courseService.getCoursesAmmount(); int courses_ammount = this.courseService.getCoursesAmmount();
@ -46,4 +57,16 @@ public class ConfiguratorServiceTest {
assertTrue(courses_ammount > 0 && groups_ammount > 0 && lecturers_ammount > 0); assertTrue(courses_ammount > 0 && groups_ammount > 0 && lecturers_ammount > 0);
} }
@Test
public void shouldRetrunNewestConfig() throws InterruptedException {
final Date dateToCheck = new Date(System.currentTimeMillis());
this.appConfigRepo.save(new AppConfig(new TourData(null, null), new TourData(null, null)));
Thread.sleep(2000);
this.appConfigRepo.save(new AppConfig(new TourData(dateToCheck, null), new TourData(null, null)));
AppConfig response = this.configuratorService.getCurrentConfig();
assertTrue(response.getFirstTourStart() != null);
}
} }

View File

@ -0,0 +1,29 @@
package com.plannaplan.services;
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.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration
public class EmailServiceTest {
@Autowired
private EmailService service;
@Test
@Ignore
/**
* This test is ignored because we don't have way to check if email has arrived.
* Check mailchater to check this manually
*/
public void shouldSendSimpleEmail() {
this.service.sendMail("shouldSendSimpleEmail@EmailService.test", "This is totally simple message");
}
}

View File

@ -8,5 +8,11 @@ spring.jpa.hibernate.ddl-auto=create-drop
spring.jackson.serialization.fail-on-empty-beans=false spring.jackson.serialization.fail-on-empty-beans=false
spring.main.allow-bean-definition-overriding=true spring.main.allow-bean-definition-overriding=true
spring.jackson.default-property-inclusion = NON_NULL spring.jackson.default-property-inclusion = NON_NULL
spring.mail.host=localhost
spring.mail.port=1025
spring.mail.properties.mail.smtp.auth=false
spring.mail.properties.mail.smtp.starttls.enable=false
plannaplan.email = plannaplan.kontakt@gmail.com
server.port=1285 server.port=1285

View File

@ -1 +1,2 @@
CREATE DATABASE IF NOT EXISTS test; CREATE DATABASE IF NOT EXISTS test;
SET GLOBAL time_zone = '+1:00';

View File

@ -17,21 +17,21 @@
<url>http://www.example.com</url> <url>http://www.example.com</url>
<profiles> <profiles>
<profile> <profile>
<id>dev</id> <id>dev</id>
<properties> <properties>
<activatedProperties>dev</activatedProperties> <activatedProperties>dev</activatedProperties>
</properties> </properties>
<activation> <activation>
<activeByDefault>true</activeByDefault> <activeByDefault>true</activeByDefault>
</activation> </activation>
</profile> </profile>
<profile> <profile>
<id>prod</id> <id>prod</id>
<properties> <properties>
<activatedProperties>prod</activatedProperties> <activatedProperties>prod</activatedProperties>
</properties> </properties>
</profile> </profile>
</profiles> </profiles>
<properties> <properties>

View File

@ -1,8 +1,10 @@
package com.plannaplan; package com.plannaplan;
import java.io.InputStream; import java.io.InputStream;
import java.sql.Date;
import com.plannaplan.models.ConfigData; import com.plannaplan.models.ConfigData;
import com.plannaplan.models.TourData;
import com.plannaplan.entities.User; import com.plannaplan.entities.User;
import com.plannaplan.services.UserService; import com.plannaplan.services.UserService;
import com.plannaplan.types.UserRoles; import com.plannaplan.types.UserRoles;
@ -14,9 +16,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.EnableScheduling;
import com.plannaplan.services.ConfiguratorService; import com.plannaplan.services.ConfiguratorService;
@SpringBootApplication @SpringBootApplication
@EnableScheduling
public class App { public class App {
public final static String API_VERSION = "v1"; public final static String API_VERSION = "v1";
@ -38,13 +43,22 @@ public class App {
SpringApplication.run(App.class, args); SpringApplication.run(App.class, args);
} }
/**
* method to import mocked data to testing app after startz. It is called only
* in dev profile
*/
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)
public void importData() { public void importData() {
System.out.println(Logo.getInitInfo(isDev)); System.out.println(Logo.getInitInfo(isDev));
if (this.isDev) { if (this.isDev) {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Zajecia.xlsx"); InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Zajecia.xlsx");
ConfigData data = new ConfigData(null, null, inputStream); ConfigData data = new ConfigData(
new TourData(new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + 86400000)),
new TourData(new Date(System.currentTimeMillis() + 86400000),
new Date(System.currentTimeMillis() + 2 * 86400000)),
inputStream);
this.contrl.config(data); this.contrl.config(data);
User newuser = new User(); User newuser = new User();
@ -109,6 +123,11 @@ public class App {
newuser.setSurname("Sad"); newuser.setSurname("Sad");
newuser.setRole(UserRoles.STUDENT); newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser); this.userService.save(newuser);
newuser = new User();
newuser.setEmail("iamnull@st.amu.edu.pl");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
} }
System.out.println(Logo.getStartedInfo(isDev)); System.out.println(Logo.getStartedInfo(isDev));

View File

@ -24,14 +24,10 @@ public class Swagger2Config extends WebMvcConfigurationSupport {
@Bean @Bean
public Docket createRestApi() { public Docket createRestApi() {
Parameter authHeader = new ParameterBuilder() Parameter authHeader = new ParameterBuilder().parameterType("header").name("Authorization")
.parameterType("header") .modelRef(new ModelRef("string")).build();
.name("Authorization")
.modelRef(new ModelRef("string"))
.build();
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage("com.plannaplan")).paths(PathSelectors.any()) .apis(RequestHandlerSelectors.basePackage("com.plannaplan")).paths(PathSelectors.any()).build()
.build()
.globalOperationParameters(Collections.singletonList(authHeader)); .globalOperationParameters(Collections.singletonList(authHeader));
} }

View File

@ -82,7 +82,7 @@ public class CommisionController extends TokenBasedController {
Assert.isTrue(!notExistingGroup.isPresent(), "Group " Assert.isTrue(!notExistingGroup.isPresent(), "Group "
+ notExistingGroup.orElse(Long.MIN_VALUE).toString() + "doesn't exist"); + notExistingGroup.orElse(Long.MIN_VALUE).toString() + "doesn't exist");
final Commision com = new Commision(user); final Commision com = new Commision(user, asker);
this.commisionService.save(com); this.commisionService.save(com);
groups.stream().forEach((groupId) -> { groups.stream().forEach((groupId) -> {

View File

@ -4,12 +4,15 @@ import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.io.IOException; import java.io.IOException;
import java.util.Date;
import com.plannaplan.App; import com.plannaplan.App;
import com.plannaplan.models.ConfigData; import com.plannaplan.models.ConfigData;
import com.plannaplan.models.TourData;
import com.plannaplan.services.ConfiguratorService; import com.plannaplan.services.ConfiguratorService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -33,13 +36,26 @@ public class ConfigController {
@Autowired @Autowired
private ConfiguratorService contrl; private ConfiguratorService contrl;
@PostMapping("/config") @PostMapping(path = "/config", consumes = { "multipart/form-data" })
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@ApiOperation("Imports data to system. To call you need to provide ADMIN token") @ApiOperation("Imports data to system. To call you need to provide ADMIN token")
public ResponseEntity<String> configApp( public ResponseEntity<String> configApp(
@RequestParam("file") @ApiParam(value = "file .xlsx that contains courses and groups with apoinnted rules") MultipartFile file) { @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 { try {
final ConfigData data = new ConfigData(null, null, file.getInputStream()); 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); this.contrl.config(data);
return new ResponseEntity<>("Sucess", HttpStatus.OK); return new ResponseEntity<>("Sucess", HttpStatus.OK);
} catch (IOException e) { } catch (IOException e) {

View File

@ -2,6 +2,7 @@ package com.plannaplan.controllers;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Optional;
import com.plannaplan.App; import com.plannaplan.App;
import com.plannaplan.entities.Groups; import com.plannaplan.entities.Groups;
@ -13,9 +14,11 @@ import com.plannaplan.services.GroupService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -57,4 +60,20 @@ public class GroupController {
} }
return new ResponseEntity<>(GroupsMappers.mapToGetCourseGroupsDefaultResponse(groups), HttpStatus.OK); return new ResponseEntity<>(GroupsMappers.mapToGetCourseGroupsDefaultResponse(groups), HttpStatus.OK);
} }
@PutMapping("/{id}/capacity")
@PreAuthorize("hasRole('ROLE_DEANERY')")
@ApiOperation(value = "Change capacity of given group. You need to provide DEANERY token to be ale to change capacity")
public ResponseEntity<String> updateCapacity(
@PathVariable(name = "id", required = true) @ApiParam(value = "id of group to change capacity") Long id,
@RequestParam(name = "newcapacity", required = true) Integer newcapacity) {
final Optional<Groups> group = this.groupService.getGroupById(id);
if (group.isEmpty()) {
return new ResponseEntity<>("Given group doens't exist", HttpStatus.NOT_FOUND);
}
final Groups gr = group.get();
gr.setCapacity(newcapacity);
this.groupService.save(gr);
return new ResponseEntity<>("Success", HttpStatus.OK);
}
} }

View File

@ -1,5 +1,8 @@
package com.plannaplan.controllers; package com.plannaplan.controllers;
import java.util.Optional;
import java.util.UUID;
import com.plannaplan.entities.User; import com.plannaplan.entities.User;
import com.plannaplan.exceptions.UserNotFoundException; import com.plannaplan.exceptions.UserNotFoundException;
import com.plannaplan.responses.models.TokenResponse; import com.plannaplan.responses.models.TokenResponse;
@ -61,4 +64,20 @@ public class TokenController {
} }
} }
@GetMapping("/token/refresh")
@ApiOperation(value = "Endpoint to access new token based on refresh token. It's needed when request with provided token fail with code 403")
public ResponseEntity<TokenResponse> getRefreshToken(
@RequestParam("refreshToken") @ApiParam(value = "Refresh token obtained in /token request") final String refreshToken)
throws NullPointerException {
Optional<User> userResult = this.userService.getUserByRefreshToken(refreshToken);
if (userResult.isEmpty()) {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
User user = userResult.get();
user.setToken(UUID.randomUUID().toString());
user = this.userService.save(user);
return new ResponseEntity<>(new TokenResponse(user), HttpStatus.OK);
}
} }

View File

@ -47,7 +47,7 @@ public class UsersController {
@PreAuthorize("hasRole('ROLE_DEANERY')") @PreAuthorize("hasRole('ROLE_DEANERY')")
@ApiOperation(value = "Gets all students. You need token with DEANERY role to call this") @ApiOperation(value = "Gets all students. You need token with DEANERY role to call this")
public ResponseEntity<List<UserResponse>> getAllStudents() { public ResponseEntity<List<UserResponse>> getAllStudents() {
final List<User> searches = this.userService.searchForStudents(""); final List<User> searches = this.userService.getAllStudents();
final List<UserResponse> response = UserResponseMappers.mapToDefaultResponse(searches); final List<UserResponse> response = UserResponseMappers.mapToDefaultResponse(searches);
return new ResponseEntity<>(response, HttpStatus.OK); return new ResponseEntity<>(response, HttpStatus.OK);
} }

View File

@ -10,12 +10,29 @@ public class CommisionResponse {
@ApiModelProperty(value = "ID created by database") @ApiModelProperty(value = "ID created by database")
private Long id; private Long id;
@ApiModelProperty(value = "ID of user that commision belongs to")
private UserResponse owner;
@ApiModelProperty(value = "ID of user that created commision")
private UserResponse commiter;
@ApiModelProperty(value = "Timestamp where the user commit the commision") @ApiModelProperty(value = "Timestamp where the user commit the commision")
private String commisionDate; private String commisionDate;
public CommisionResponse(Commision commision) { public CommisionResponse(Commision commision) {
this.id = commision.getId(); this.id = commision.getId();
this.commisionDate = commision.getCommisionDate().toString(); this.commisionDate = commision.getCommisionDate().toString();
this.owner = commision.getCommisionOwner() != null ? new UserResponse(commision.getCommisionOwner()) : null;
this.commiter = commision.getCommisionCommiter() != null ? new UserResponse(commision.getCommisionCommiter())
: null;
}
public UserResponse getCommiter() {
return commiter;
}
public UserResponse getOwner() {
return owner;
} }
public String getCommisionDate() { public String getCommisionDate() {

View File

@ -21,6 +21,9 @@ public class GroupDefaultResponse {
@ApiModelProperty(value = "Value shows time when the course takes.") @ApiModelProperty(value = "Value shows time when the course takes.")
private String time; private String time;
@ApiModelProperty(value = "Value shows time when the course ends.")
private String endTime;
@ApiModelProperty(value = "Value shows degree, name and surname.") @ApiModelProperty(value = "Value shows degree, name and surname.")
private String lecturer; private String lecturer;
@ -37,6 +40,7 @@ public class GroupDefaultResponse {
this.id = group.getId() != null ? group.getId() : null; this.id = group.getId() != null ? group.getId() : null;
this.day = group.getDay() != null ? group.getDay().label : -1; this.day = group.getDay() != null ? group.getDay().label : -1;
this.time = group.getTimeString() != null ? group.getTimeString() : ""; this.time = group.getTimeString() != null ? group.getTimeString() : "";
this.endTime = group.getEndTimeString() != null ? group.getEndTimeString() : "";
this.lecturer = group.getLecturer() != null ? group.getLecturer().toString() : ""; this.lecturer = group.getLecturer() != null ? group.getLecturer().toString() : "";
this.room = group.getRoom() != null ? group.getRoom() : ""; this.room = group.getRoom() != null ? group.getRoom() : "";
this.type = group.getType() != null ? group.getType() : null; this.type = group.getType() != null ? group.getType() : null;
@ -67,6 +71,10 @@ public class GroupDefaultResponse {
return time; return time;
} }
public String getEndTime() {
return endTime;
}
public int getDay() { public int getDay() {
return day; return day;
} }

View File

@ -9,6 +9,8 @@ import io.swagger.annotations.ApiModelProperty;
public class TokenResponse { public class TokenResponse {
@ApiModelProperty(value = "user token used to verify requests") @ApiModelProperty(value = "user token used to verify requests")
private String token; private String token;
@ApiModelProperty(value = "user token needed to refresh")
private String refreshToken;
@ApiModelProperty(value = "user id in database") @ApiModelProperty(value = "user id in database")
private Long id; private Long id;
@ApiModelProperty(value = "user app role") @ApiModelProperty(value = "user app role")
@ -21,6 +23,7 @@ public class TokenResponse {
this.authorityRole = user.getRole().toString(); this.authorityRole = user.getRole().toString();
this.email = user.getEmail(); this.email = user.getEmail();
this.token = user.getToken(); this.token = user.getToken();
this.refreshToken = user.getRefreshToken();
} }
public String getEmail() { public String getEmail() {
@ -39,4 +42,8 @@ public class TokenResponse {
return token; return token;
} }
public String getRefreshToken() {
return this.refreshToken;
}
} }

View File

@ -14,8 +14,8 @@ public class UserResponse {
public UserResponse(User user) { public UserResponse(User user) {
this.id = user.getId(); this.id = user.getId();
this.name = user.getName(); this.name = user.getName() != null ? user.getName() : "";
this.surname = user.getSurname(); this.surname = user.getSurname() != null ? user.getSurname() : "";
this.email = user.getEmail(); this.email = user.getEmail();
} }

View File

@ -37,9 +37,10 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
public void configure(final WebSecurity webSecurity) { public void configure(final WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/token**").antMatchers("/api/v1/courses/all") webSecurity.ignoring().antMatchers("/token**").antMatchers("/token/refresh**")
.antMatchers("/api/v1/groups/course/{id}").antMatchers("/v2/api-docs", "/configuration/ui", .antMatchers("/api/v1/courses/all").antMatchers("/api/v1/groups/course/{id}")
"/swagger-resources/**", "/configuration/security", "/swagger-ui.html", "/webjars/**"); .antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/security",
"/swagger-ui.html", "/webjars/**");
} }
@Override @Override

View File

@ -9,6 +9,11 @@
"name": "plannaplan.frontendUrl", "name": "plannaplan.frontendUrl",
"type": "java.lang.String", "type": "java.lang.String",
"description": "Url where frontend app is located" "description": "Url where frontend app is located"
},
{
"name": "plannaplan.email",
"type": "java.lang.String",
"description": "Email from which app sends message"
} }
] ]
} }

View File

@ -8,6 +8,14 @@ spring.jpa.hibernate.ddl-auto=create-drop
spring.jackson.serialization.fail-on-empty-beans=false spring.jackson.serialization.fail-on-empty-beans=false
spring.main.allow-bean-definition-overriding=true spring.main.allow-bean-definition-overriding=true
spring.jackson.default-property-inclusion = NON_NULL spring.jackson.default-property-inclusion = NON_NULL
spring.mail.host=localhost
spring.mail.port=1025
# spring.mail.username=<login user to smtp server>
# spring.mail.password=<login password to smtp server>
spring.mail.properties.mail.smtp.auth=false
spring.mail.properties.mail.smtp.starttls.enable=false
logging.level.io.swagger.models.parameters.AbstractSerializableParameter=ERROR
server.port=1285 server.port=1285
plannaplan.dev = true plannaplan.dev = true
plannaplan.frontendUrl= http://localhost:3000 plannaplan.frontendUrl = http://localhost:3000
plannaplan.email = plannaplan.kontakt@gmail.com

View File

@ -8,13 +8,20 @@ spring.jpa.hibernate.ddl-auto=update
spring.jackson.serialization.fail-on-empty-beans=false spring.jackson.serialization.fail-on-empty-beans=false
spring.main.allow-bean-definition-overriding=true spring.main.allow-bean-definition-overriding=true
spring.jackson.default-property-inclusion = NON_NULL spring.jackson.default-property-inclusion = NON_NULL
logging.level.io.swagger.models.parameters.AbstractSerializableParameter=ERROR
spring.mail.host=${PLANNAPLAN_EMAIL_HOST}
spring.mail.port=${PLANNAPLAN_EMAIL_PORT}
spring.mail.username=${PLANNAPLAN_EMAIL_USERNAME}
spring.mail.password=${PLANNAPLAN_EMAIL_PASSWORD}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
server.port=1285 server.port=1285
plannaplan.email = ${PLANNAPLAN_EMAIL}
plannaplan.dev = false plannaplan.dev = false
plannaplan.frontendUrl= https://wmi.plannaplan.pl plannaplan.frontendUrl= https://wmi.plannaplan.pl
security.require-ssl=true security.require-ssl=true
server.ssl.key-store=/keys/keystore.p12 server.ssl.key-store=/keys/keystore.p12
server.ssl.key-store-password= server.ssl.key-store-password=
server.ssl.keyStoreType=PKCS12 server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat server.ssl.keyAlias=tomcat

View File

@ -2,11 +2,15 @@ package com.plannaplan.controllers;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
import java.io.InputStream; import java.io.InputStream;
import java.sql.Date;
import com.plannaplan.entities.AppConfig;
import com.plannaplan.entities.User; import com.plannaplan.entities.User;
import com.plannaplan.services.ConfiguratorService;
import com.plannaplan.services.UserService; import com.plannaplan.services.UserService;
import com.plannaplan.types.UserRoles; import com.plannaplan.types.UserRoles;
@ -28,9 +32,15 @@ public class ConfigControllerTest extends AbstractControllerTest {
private static final String FILE_NAME = "Zajecia.xlsx"; private static final String FILE_NAME = "Zajecia.xlsx";
private static final String CONFIG_ENDPOINT = "/api/v1/configurator/config"; private static final String CONFIG_ENDPOINT = "/api/v1/configurator/config";
private static final String FIRST_TOUR_START = "firstTourBegin";
private static final String FIRST_TOUR_END = "firstTourEnd";
private static final String SECOND_TOUR_START = "secondTourBegin";
private static final String SECOND_TOUR_END = "secondTourEnd";
@Autowired @Autowired
private UserService service; private UserService service;
@Autowired
private ConfiguratorService configService;
@Test @Test
public void shouldReturnNoAuthorized() throws Exception { public void shouldReturnNoAuthorized() throws Exception {
@ -52,11 +62,40 @@ public class ConfigControllerTest extends AbstractControllerTest {
final String token = this.service.login(usr).getToken(); final String token = this.service.login(usr).getToken();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(multipart(CONFIG_ENDPOINT).file(file).header("Authorization", "Bearer " + token)) mockMvc.perform(multipart(CONFIG_ENDPOINT).file(file).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()); .andExpect(status().isOk());
} }
@Test
public void shouldInsertedDataBeSameInDatabase() throws Exception {
final String mail = "shouldReturnOKAuthorized@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(CONFIG_ENDPOINT).file(file).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());
final AppConfig config = this.configService.getCurrentConfig();
assertTrue(config.getFirstTourStart().compareTo(Date.valueOf("2020-12-12")) == 0,
"Date in database is wrong. Perhabs database has wrong timezone set.");
assertTrue(config.getFirstTourEnd().compareTo(Date.valueOf("2020-12-14")) == 0,
"Date in database is wrong. Perhabs database has wrong timezone set.");
assertTrue(config.getSecondTourStart().compareTo(Date.valueOf("2020-12-16")) == 0,
"Date in database is wrong. Perhabs database has wrong timezone set.");
assertTrue(config.getSecondTourEnd().compareTo(Date.valueOf("2020-12-20")) == 0,
"Date in database is wrong. Perhabs database has wrong timezone set.");
// yyyy-mm-dd
}
@Test @Test
public void shouldReturnDenyNoAdminAuthorized() throws Exception { public void shouldReturnDenyNoAdminAuthorized() throws Exception {
final String mail = "shouldReturnDenyNoAdminAuthorized@ConfigController.test"; final String mail = "shouldReturnDenyNoAdminAuthorized@ConfigController.test";
@ -72,4 +111,112 @@ public class ConfigControllerTest extends AbstractControllerTest {
} }
@Test
public void shouldFailDueToWrongFirstTour() throws Exception {
final String mail = "shouldFailDueToWrongFirstTour@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(CONFIG_ENDPOINT).file(file).param(FIRST_TOUR_START, "12.12.2020")
.param(FIRST_TOUR_END, "12.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 shouldFailDueToWrongSecondTour() throws Exception {
final String mail = "shouldFailDueToWrongSecondTour@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(CONFIG_ENDPOINT).file(file).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, "16.12.2020").header("Authorization", "Bearer " + token))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldFailDueToWrongBothTour() throws Exception {
final String mail = "shouldFailDueToWrongBothTour@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(CONFIG_ENDPOINT).file(file).param(FIRST_TOUR_START, "12.12.2020")
.param(FIRST_TOUR_END, "12.12.2020").param(SECOND_TOUR_START, "16.12.2020")
.param(SECOND_TOUR_END, "16.12.2020").header("Authorization", "Bearer " + token))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldFailDueToWrongTourTransition() throws Exception {
final String mail = "shouldFailDueToWrongTourTransition@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(CONFIG_ENDPOINT).file(file).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, "16.12.2020").header("Authorization", "Bearer " + token))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldFailDueToWrongDateFormat() throws Exception {
final String mail = "shouldFailDueToWrongDateFormat@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(CONFIG_ENDPOINT).file(file).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());
}
@Test
public void shouldFailDueToNoDate() throws Exception {
final String mail = "shouldFailDueToNoDate@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(CONFIG_ENDPOINT).file(file).header("Authorization", "Bearer " + token))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldFailDueToNoFile() throws Exception {
final String mail = "shouldFailDueToNoFile@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(multipart(CONFIG_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());
}
} }

View File

@ -2,6 +2,7 @@ package com.plannaplan.controllers;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
@ -9,7 +10,17 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 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.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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.springSecurity;
import com.plannaplan.entities.Groups;
import com.plannaplan.entities.User;
import com.plannaplan.services.GroupService;
import com.plannaplan.services.UserService;
import com.plannaplan.types.UserRoles;
import com.plannaplan.types.WeekDay;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest
@ -17,6 +28,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class GroupControllerTest extends AbstractControllerTest { public class GroupControllerTest extends AbstractControllerTest {
private static final String GROUPS_BY_COURSE_ENDPOINT = "/api/v1/groups/course"; private static final String GROUPS_BY_COURSE_ENDPOINT = "/api/v1/groups/course";
private static final String UPDATE_GROUPS_ENDPOINT = "/api/v1/groups/521/capacity";
@Autowired
private UserService service;
@Autowired
private GroupService groupService;
@Test @Test
public void shouldFailWithNoParaeter() throws Exception { public void shouldFailWithNoParaeter() throws Exception {
@ -29,4 +47,59 @@ public class GroupControllerTest extends AbstractControllerTest {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(get(GROUPS_BY_COURSE_ENDPOINT + "/2")).andExpect(status().isOk()); mockMvc.perform(get(GROUPS_BY_COURSE_ENDPOINT + "/2")).andExpect(status().isOk());
} }
@Test
public void shouldFailWithNoToken() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(put(UPDATE_GROUPS_ENDPOINT)).andExpect(status().is4xxClientError());
}
@Test
public void shouldFailWithStudentToken() throws Exception {
final User user = this.service
.save(new User(null, null, "shouldFailWithStudentToken@GroupController.test", UserRoles.STUDENT));
final String token = this.service.login(user).getToken();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(put(UPDATE_GROUPS_ENDPOINT).header("Authorization", "Bearer " + token))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldFailWithNoParams() throws Exception {
final User user = this.service
.save(new User(null, null, "shouldFailWithNoParams@GroupController.test", UserRoles.DEANERY));
final String token = this.service.login(user).getToken();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(put(UPDATE_GROUPS_ENDPOINT).header("Authorization", "Bearer " + token))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldFailWithWrongId() throws Exception {
final User user = this.service
.save(new User(null, null, "shouldFailWithWrongId@GroupController.test", UserRoles.DEANERY));
final String token = this.service.login(user).getToken();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(put("/api/v1/groups/" + user.getId() + "/capacity").param("newcapacity", "23")
.header("Authorization", "Bearer " + token)).andExpect(status().isNotFound());
}
@Test
public void shouldChangeCapacity() throws Exception {
final User user = this.service
.save(new User(null, null, "shouldChangeCapacity@GroupController.test", UserRoles.DEANERY));
final String token = this.service.login(user).getToken();
final Groups newGroup = this.groupService.save(new Groups(43, "A-Nigzdie", null, 436, WeekDay.FRIDAY, null));
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(put("/api/v1/groups/" + newGroup.getId() + "/capacity").param("newcapacity", "23")
.header("Authorization", "Bearer " + token)).andExpect(status().isOk());
assertTrue(this.groupService.getGroupById(newGroup.getId()).get().getCapacity() == 23);
}
} }

View File

@ -3,6 +3,7 @@ package com.plannaplan.controllers;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
@ -12,11 +13,22 @@ 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.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import com.plannaplan.entities.User;
import com.plannaplan.services.UserService;
import com.plannaplan.types.UserRoles;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest
@ContextConfiguration @ContextConfiguration
public class TokenControllerTest extends AbstractControllerTest { public class TokenControllerTest extends AbstractControllerTest {
private final String TOKEN_ENDPOINT = "/token"; private final String TOKEN_ENDPOINT = "/token";
private final String REFRESH_TOKEN_ENDPOINT = "/token/refresh";
@Autowired
private UserService service;
@Test @Test
public void shouldFailWithNoParameter() throws Exception { public void shouldFailWithNoParameter() throws Exception {
@ -39,4 +51,39 @@ public class TokenControllerTest extends AbstractControllerTest {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(get(TOKEN_ENDPOINT).param("ticket", ticket)).andExpect(status().isOk()); mockMvc.perform(get(TOKEN_ENDPOINT).param("ticket", ticket)).andExpect(status().isOk());
} }
@Test
public void shouldFailWithWrongRefreshToken() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(get(REFRESH_TOKEN_ENDPOINT).param("refreshToken", "totaly-wrong-refresh-token"))
.andExpect(status().is4xxClientError());
}
@Test
public void shouldRetrunTokenBeforeExpirationOfOldOne() throws Exception {
User user = new User("Eren", "Yager", "shouldRetrunTokenBeforeExpirationOfOldOne@TokenController.test",
UserRoles.TEST_USER);
user.setToken("Totalnie-bezpieczny-token");
this.service.save(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(get(REFRESH_TOKEN_ENDPOINT).param("refreshToken", user.getRefreshToken()))
.andExpect(status().isOk());
}
@Test
public void shouldRetrunTokenAfterExpirationOfOldOne() throws Exception {
final Field reader = User.class.getDeclaredField("tokenUsageDate");
reader.setAccessible(true);
User user = new User("Mikasa", "Ackerman", "shouldRetrunTokenAfterExpirationOfOldOne@TokenController.test",
UserRoles.TEST_USER);
user.setToken("Totalnie-bezpieczny-token");
reader.set(user, new Timestamp(System.currentTimeMillis() - 86400000));
this.service.save(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(get(REFRESH_TOKEN_ENDPOINT).param("refreshToken", user.getRefreshToken()))
.andExpect(status().isOk());
}
} }

View File

@ -1,5 +1,6 @@
package com.plannaplan.security.cas; package com.plannaplan.security.cas;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -9,12 +10,15 @@ public class CustomUAMCasValidatorTest {
private String serviceUrl; private String serviceUrl;
@Test @Test
@Ignore
public void shouldValidateWithDomain() { public void shouldValidateWithDomain() {
// you need to privide fresh ticket to make this test pass that's why it is
CustomUAMCasValidator validator = new CustomUAMCasValidator(serviceUrl, "ST-54649-5x4h09vzUpEIyAGmf1sz-cas.amu.edu.pl"); // marked as ignored
validator.validate();
CustomUAMCasValidator validator = new CustomUAMCasValidator(serviceUrl,
"ST-54649-5x4h09vzUpEIyAGmf1sz-cas.amu.edu.pl");
validator.validate();
} }
} }

View File

@ -20,3 +20,9 @@ services:
restart: always restart: always
ports: ports:
- 8080:8080 - 8080:8080
mailcatcher:
image: schickling/mailcatcher:latest
ports:
- "127.0.0.1:1080:1080"
- "127.0.0.1:1025:1025"