Merge pull request 'new-cas-configuration' (#27) from new-cas-configuration into master

Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/27
This commit is contained in:
Marcin Woźniak 2020-12-07 21:10:49 +01:00
commit b412ee2a5b
26 changed files with 487 additions and 158 deletions

View File

@ -3,20 +3,7 @@
Zeby wystartowac aplikacje backendu najpierw nalezy postawic testowa baze danych na naszym komputerze za pomoca dockera. Jesli raz juz go odpalimy przy nastepnym razem bardzo mozliwe, ze wlaczy sie sam. AAby sprawdzic czy docker jesty wystartowany mozna uzyc `docker ps`
```
docker-compose -f stack.yml up
```
Nastepnie w `restservice/src/main/resources/application.properties` nalezy podac ip naszego kontenera.
```
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=example
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=create
server.port=1285
docker-compose -f stack.yml up -d
```
Następnym krokiem jest odpalenie poniższych komend w terminalu.
@ -26,7 +13,7 @@ cd restservice
mvn spring-boot:run
```
## Token
## Token obtaining
Żeby tesotwać API wpełni potrzebny nam jest token który otrzymujemy na podstawie ticketa z systemu autoryzacyjnego **CAS**. Z tego powodu system autoryzacji działa inaczej niż w "książkowych" restowych aplikacjach i np Postman za nas jej nie dokona. Musimy mu podać już uzyskany token. Aby łatwo go uzyskać odpal skrypt
@ -36,13 +23,23 @@ python gettoken.py
Na koniec w przęglądarce dostaniesz w odpowiedzi token. W samym pliku można zmienić porty aplikacji jeśli to potrzebne.
## Api docs
## Profiles
Żeby zobaczyć dokumentację api trzeba wejść w przeglądarce na `http://localhost:1285/swagger-ui.html` po odpaleniu aplikacji.
W aplikacji posiadamy dwa profile. `dev` i `prod`. **Dev** używamy do testowania aplikacji lokalnie. **Pord** służy do stworzenia builda na produkcję.
Profil wybieramy w pliku `restservice/src/main/resources/application.properties` wpisując odpowiednią nazwę
### Nazewnictwo odpowiedzi
```
spring.profiles.active=prod
```
Każdą odp zaczynamy od modelu, który opisuje np. `Courses` a kończymy na `Response`. Między tymi dwoma członami możemy dodawać modyfikatory opisujące dokładniej odpowiedź np. `Default`. W ten sposób możemy otrzymać nazwę `CoursesDefaultResponse.java`
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:
- PLANNAPLAN_MYSQL_DB_HOST - host bazy danych np `localhost`
- 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_USERNAME - nazwa użytkownika bazy
- PLANNAPLAN_MYSQL_DB_PASSWORD - hasło użytkownika bazy
## Packaging
@ -57,12 +54,22 @@ 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)
## Generowanie dokumentacji - javadoc
## Generowanie dokumentacji
### Javadocs
```bash
mvn javadoc:javadoc
```
### Api docs
Żeby zobaczyć dokumentację api trzeba wejść w przeglądarce na `http://localhost:1285/swagger-ui.html` po odpaleniu aplikacji.
#### Nazewnictwo odpowiedzi
Każdą odpowiedź zaczynamy od modelu, który opisuje np. `Courses` a kończymy na `Response`. Między tymi dwoma członami możemy dodawać modyfikatory opisujące dokładniej odpowiedź np. `Default`. W ten sposób możemy otrzymać nazwę `CoursesDefaultResponse.java`
## Troubleshooting
Spring chyba cacheuje jakies dane dotyczace polaczenia wiec jesli spring wywali Ci blad `Connection Refused`, a wiesz, ze ta baza stoi na podanym ip i porcie to sprobuj

View File

@ -24,9 +24,11 @@ public class User {
private String name;
private String surname;
private String email;
private String usosId;
private UserRoles role;
private String token;
private Timestamp tokenUsageDate;
public User() {
}
@ -46,6 +48,29 @@ public class User {
this.role = role;
}
/*
* User
*
* @param name name given to the user
* @param surname surname given to the user
* @param email mail given to the user
* @param usosId id in the USOS system
* @param role role given to the user
*/
public User(String name, String surname, String mail, String usosId, UserRoles role){
this(name,surname,mail,role);
this.usosId = usosId;
}
/*
* getusosId
*
* @return usosId
*/
public String getUsosId() {
return usosId;
}
/*
* getEmail
*

View File

@ -50,4 +50,7 @@ public interface UserRepository extends JpaRepository<User, Long> {
@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);
@Query("FROM User WHERE usosId = ?1")
Optional<User> getByUsosId(@Param("usosId") String usosId);
}

View File

@ -24,13 +24,38 @@ public class UserService {
super();
}
public String login(String authority) throws UserNotFoundException {
User user = this.repo.getByAuthority(authority.replace("\n", "").trim())
.orElseThrow(() -> new UserNotFoundException("Can not find user with given authority"));
public User checkForUser(String email, String usosId) {
if (usosId == null) {
Optional <User> user = this.repo.getByAuthority(email.replace("\n", "").trim());
if (user.isPresent()){
return user.get();
}
else {
final User newUser = new User(null,null,email.replace("\n", "").trim(),UserRoles.STUDENT);
return this.repo.save(newUser);
}
}
else {
Optional <User> user = this.repo.getByUsosId(usosId.replace("\n", "").trim());
if (user.isPresent()){
return user.get();
}
else {
final User newUser = new User(null,null,email.replace("\n", "").trim(),usosId,UserRoles.STUDENT);
return this.repo.save(newUser);
}
}
}
public String login(User authority) throws UserNotFoundException {
final String token = UUID.randomUUID().toString();
user.setToken(token);
this.repo.save(user);
try{
authority.setToken(token);
this.repo.save(authority);
}
catch (Exception e){
throw new UserNotFoundException(e.getMessage());
}
return token;
}

View File

@ -32,10 +32,9 @@ public class UserServiceTest {
@Test
public void shouldReturnToken() {
final User testUser = new User(TEST_USER_NAME, TEST_USER_SUERNAME, TEST_USER_MAIL, UserRoles.TEST_USER);
this.userService.save(testUser);
final User testUser = this.userService.save(new User(TEST_USER_NAME, TEST_USER_SUERNAME, TEST_USER_MAIL, UserRoles.TEST_USER));
try {
final String token = this.userService.login(TEST_USER_MAIL);
final String token = this.userService.login(testUser);
System.out.println("Returned token: " + token);
assertTrue(token != null);
assertTrue(this.userService.getUserByEmail(TEST_USER_MAIL).getToken() != null);
@ -45,16 +44,6 @@ public class UserServiceTest {
}
}
@Test
public void shouldThrowException() {
try {
this.userService.login("thiseamilisnotindatabase@gmail.com");
assertTrue(false);
} catch (UserNotFoundException e) {
assertTrue(true);
}
}
@Test
public void shouldFindStudents() {
this.userService.save(new User("Nemo", "TheFish", "Nemo@shouldFindStudents.test", UserRoles.STUDENT));
@ -93,4 +82,21 @@ public class UserServiceTest {
private boolean containsName(final List<User> list, final String name) {
return list.stream().map(User::getName).filter(name::equals).findFirst().isPresent();
}
@Test
public void shouldCreateUser(){
final User user = this.userService.checkForUser("shouldCreateUser@UserService.test", null);
assertTrue(user.getId() != null);
}
@Test
public void shouldReturnExistingUser(){
final String email = "shouldReturnExistingUser@UserService.test";
this.userService.save(new User("Tom","Smieszne",email,UserRoles.TEST_USER));
final User user = this.userService.checkForUser(email, null);
assertTrue(user.getName() != "Tom");
}
}

View File

@ -16,6 +16,24 @@
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
</profile>
</profiles>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
@ -57,6 +75,13 @@
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core -->
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>

View File

@ -1,24 +1,35 @@
package com.plannaplan;
import java.io.InputStream;
import com.plannaplan.models.ConfigData;
import com.plannaplan.entities.User;
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.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import com.plannaplan.services.ConfiguratorService;
@SpringBootApplication
public class App {
public final static String API_VERSION = "v1";
@Autowired
private ConfiguratorService contrl;
@Autowired
UserService userService;
@Value("${plannaplan.dev}")
private boolean isDev;
public static void main(String[] args) {
Logo logo = new Logo("beta");
System.out.println(logo.getLogo());
@ -29,33 +40,78 @@ public class App {
@EventListener(ApplicationReadyEvent.class)
public void importData() {
User filip = new User();
filip.setEmail("filizy@st.amu.edu.pl");
filip.setName("Filip");
filip.setSurname("Izydorczyk");
filip.setRole(UserRoles.STUDENT);
this.userService.save(filip);
System.out.println(Logo.getInitInfo(isDev));
User hub = new User();
hub.setEmail("hubwrz1@st.amu.edu.pl");
hub.setName("Hubert");
hub.setSurname("Wrzesiński");
hub.setRole(UserRoles.STUDENT);
this.userService.save(hub);
if (this.isDev) {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("Zajecia.xlsx");
ConfigData data = new ConfigData(null, null, inputStream);
this.contrl.config(data);
User mac = new User();
mac.setEmail("macglo2@st.amu.edu.pl");
mac.setName("Maciej");
mac.setSurname("Głowacki");
mac.setRole(UserRoles.STUDENT);
this.userService.save(mac);
User newuser = new User();
newuser.setEmail("tommy@st.amu.edu.pl");
newuser.setName("Tomek");
newuser.setSurname("Atomek");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
User mar = new User();
mar.setEmail("marwoz16@st.amu.edu.pl");
mar.setName("Marcin");
mar.setSurname("Woźniak");
mar.setRole(UserRoles.ADMIN);
this.userService.save(mar);
newuser = new User();
newuser.setEmail("robercik@st.amu.edu.pl");
newuser.setName("Robert");
newuser.setSurname("Głowacki");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("mewa@st.amu.edu.pl");
newuser.setName("Poznanska");
newuser.setSurname("Mewa");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("tkul2@st.amu.edu.pl");
newuser.setName("Tomasz");
newuser.setSurname("Kula");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("annana@st.amu.edu.pl");
newuser.setName("Anna");
newuser.setSurname("Na");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("mnart@st.amu.edu.pl");
newuser.setName("Marta");
newuser.setSurname("Narta");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("zmineniane@st.amu.edu.pl");
newuser.setName("Tutaj");
newuser.setSurname("Koncza");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("mi@st.amu.edu.pl");
newuser.setName("Mi");
newuser.setSurname("Sie");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
newuser = new User();
newuser.setEmail("pms@st.amu.edu.pl");
newuser.setName("Pomysly");
newuser.setSurname("Sad");
newuser.setRole(UserRoles.STUDENT);
this.userService.save(newuser);
}
System.out.println(Logo.getStartedInfo(isDev));
}
}

View File

@ -1,11 +1,14 @@
package com.plannaplan;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Logo {
public static final String ANSI_RESET = "\u001B[0m";
public static final String ANSI_YELLOW = "\u001B[33m";
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_BLACK = "\u001B[30m";
public static final String ANSI_BLACK = "\u001B[37m";
private String version;
public Logo(String version){
@ -30,4 +33,25 @@ public class Logo {
ANSI_RESET;
return result;
}
public static String getInitInfo(boolean isDev){
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime now = LocalDateTime.now();
if(isDev){
return ANSI_BLACK + dtf.format(now) + ANSI_YELLOW + " plannaplan" + ANSI_RESET + " initializing [" +ANSI_BLUE + "dev" + ANSI_RESET +"]";
}
return ANSI_BLACK + dtf.format(now) + ANSI_YELLOW + " plannaplan" + ANSI_RESET + " initializing [" +ANSI_BLUE + "prod" + ANSI_RESET +"]";
}
public static String getStartedInfo(boolean isDev){
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime now = LocalDateTime.now();
if(isDev){
return ANSI_BLACK + dtf.format(now) +ANSI_YELLOW + " plannaplan" + ANSI_RESET + " started [" +ANSI_BLUE + "dev" + ANSI_RESET +"]";
}
return ANSI_BLACK + dtf.format(now) + ANSI_YELLOW + " plannaplan" + ANSI_RESET + " started [" +ANSI_BLUE + "prod" + ANSI_RESET +"]";
}
}

View File

@ -1,11 +1,16 @@
package com.plannaplan.controllers;
import com.plannaplan.entities.User;
import com.plannaplan.exceptions.UserNotFoundException;
import com.plannaplan.security.CasValidationExcepiton;
import com.plannaplan.security.CasValidator;
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.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
@ -22,7 +27,11 @@ import io.swagger.annotations.ApiParam;
@Api(tags = { "Token" }, value = "Token", description = "Enpoints to get authorization.")
public class TokenController {
private final static String SERVICE_URL = "http://localhost:3000";
@Value("${plannaplan.frontendUrl}")
private String serviceUrl;
@Value("${plannaplan.dev}")
private boolean isDev;
@Autowired
private UserService userService;
@ -30,12 +39,15 @@ public class TokenController {
@GetMapping("/token")
@ApiOperation(value = "Endpoint to access token required to call secured endpoints. In order to access token we need to provide access token comming from unviersity CAS system")
public ResponseEntity<String> getToken(
@RequestParam("ticket") @ApiParam(value = "Ticket get from CAS system. It should look like ST-1376572-wo41gty5R0JCZFKMMie2-cas.amu.edu.pl") final String ticket) {
final CasValidator validator = new CasValidator(SERVICE_URL, ticket);
@RequestParam("ticket") @ApiParam(value = "Ticket get from CAS system. It should look like ST-1376572-wo41gty5R0JCZFKMMie2-cas.amu.edu.psl") final String ticket) {
final CasValidator validator = isDev ? new DefaultUAMCasValidator(serviceUrl, ticket) : new CustomUAMCasValidator(serviceUrl, ticket);
try {
String authority = validator.validate();
String token = this.userService.login(authority);
final CasUserIdentity casUserIdentity = validator.validate();
final String usosId = casUserIdentity.getUsosId();
final String authority = casUserIdentity.getEmail();
final User user = this.userService.checkForUser(authority, usosId);
String token = this.userService.login(user);
return new ResponseEntity<>(token, HttpStatus.OK);
} catch (CasValidationExcepiton e) {
return new ResponseEntity<>("Wrong ticket", HttpStatus.UNAUTHORIZED);

View File

@ -1,45 +0,0 @@
package com.plannaplan.security;
import java.net.URLEncoder;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class CasValidator {
private static String CAS_URL = "https://cas.amu.edu.pl/cas";
private final CloseableHttpClient httpClient = HttpClients.createDefault();
private String service;
private String ticket;
public CasValidator(String service, String ticket) {
this.service = service;
this.ticket = ticket;
}
public String validate() throws Exception, CasValidationExcepiton {
HttpGet request = new HttpGet(CasValidator.CAS_URL + "/validate?service="
+ URLEncoder.encode(this.service, "UTF-8") + "&ticket=" + URLEncoder.encode(this.ticket, "UTF-8"));
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
// return it as a String
result = EntityUtils.toString(entity);
if (result.replace("\n", "").trim().equals("no")) {
throw new CasValidationExcepiton("Validation failed");
}
}
String res = result.substring(result.indexOf('\n') + 1);
return res;
}
}
}

View File

@ -0,0 +1,19 @@
package com.plannaplan.security.cas;
public class CasUserIdentity {
private String usosId;
private String email;
public CasUserIdentity(String usosId, String email){
this.usosId = usosId;
this.email = email;
}
public String getUsosId() {
return usosId;
}
public String getEmail() {
return email;
}
}

View File

@ -1,4 +1,4 @@
package com.plannaplan.security;
package com.plannaplan.security.cas;
public class CasValidationExcepiton extends RuntimeException {
/**

View File

@ -0,0 +1,6 @@
package com.plannaplan.security.cas;
public interface CasValidator {
CasUserIdentity validate();
}

View File

@ -0,0 +1,46 @@
package com.plannaplan.security.cas;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidationException;
public class CustomUAMCasValidator implements CasValidator {
private static String CAS_URL = "https://cas.amu.edu.pl/cas";
private static String EMAIL_FIELD = "mail";
private static String USOS_ID = "usos_id";
private String service;
private String ticket;
public CustomUAMCasValidator(String service, String ticket){
this.service = service;
this.ticket = ticket;
}
@Override
public CasUserIdentity validate() {
/*
* TO DO
* Dodać case z CAS10/CAS20/CAS30
*/
final Cas20ServiceTicketValidator validator = new Cas20ServiceTicketValidator(CustomUAMCasValidator.CAS_URL);
try {
final Assertion assertion = validator.validate(this.ticket, this.service);
if (assertion == null) {
throw new CasValidationExcepiton("Validation failed. Assertion could not be retrieved for ticket " + "");
}
final String usosid = assertion.getPrincipal().getAttributes().get(CustomUAMCasValidator.USOS_ID).toString();
final String mail = assertion.getPrincipal().getAttributes().get(CustomUAMCasValidator.EMAIL_FIELD).toString();
return new CasUserIdentity(usosid,mail);
} catch (TicketValidationException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,51 @@
package com.plannaplan.security.cas;
import java.net.URLEncoder;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class DefaultUAMCasValidator implements CasValidator {
private static String CAS_URL = "https://cas.amu.edu.pl/cas";
private final CloseableHttpClient httpClient = HttpClients.createDefault();
private String service;
private String ticket;
public DefaultUAMCasValidator(String service, String ticket) {
this.service = service;
this.ticket = ticket;
}
@Override
public CasUserIdentity validate() {
try {
HttpGet request = new HttpGet(DefaultUAMCasValidator.CAS_URL + "/validate?service="
+ URLEncoder.encode(this.service, "UTF-8") + "&ticket=" + URLEncoder.encode(this.ticket, "UTF-8"));
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
String result = null;
if (entity != null) {
// return it as a String
result = EntityUtils.toString(entity);
if (result.replace("\n", "").trim().equals("no")) {
throw new CasValidationExcepiton("Validation failed");
}
}
String res = result.substring(result.indexOf('\n') + 1);
return new CasUserIdentity(null,res);
}
}
catch (Exception e) {
throw new CasValidationExcepiton("Cas Validation has failed.");
}
}
}

View File

@ -0,0 +1,14 @@
{
"properties": [
{
"name": "plannaplan.dev",
"type": "java.lang.String",
"description": "Should application create resorces for development or not"
},
{
"name": "plannaplan.frontendUrl",
"type": "java.lang.String",
"description": "Url where frontend app is located"
}
]
}

Binary file not shown.

View File

@ -0,0 +1,13 @@
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=example
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.open-in-view=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jackson.serialization.fail-on-empty-beans=false
spring.main.allow-bean-definition-overriding=true
spring.jackson.default-property-inclusion = NON_NULL
server.port=1285
plannaplan.dev = true
plannaplan.frontendUrl= http://localhost:3000

View File

@ -0,0 +1,20 @@
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.datasource.url = jdbc:mysql://${PLANNAPLAN_MYSQL_DB_HOST}:${PLANNAPLAN_MYSQL_DB_PORT}/${PLANNAPLAN_MYSQL_DB}?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username = ${PLANNAPLAN_MYSQL_DB_USERNAME}
spring.datasource.password = ${PLANNAPLAN_MYSQL_DB_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.open-in-view=true
spring.jpa.hibernate.ddl-auto=update
spring.jackson.serialization.fail-on-empty-beans=false
spring.main.allow-bean-definition-overriding=true
spring.jackson.default-property-inclusion = NON_NULL
server.port=1285
plannaplan.dev = false
plannaplan.frontendUrl= https://wmi.plannaplan.pl
security.require-ssl=true
server.ssl.key-store=/keys/keystore.p12
server.ssl.key-store-password=
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat

View File

@ -1,12 +1 @@
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=example
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.open-in-view=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jackson.serialization.fail-on-empty-beans=false
spring.main.allow-bean-definition-overriding=true
spring.jackson.default-property-inclusion = NON_NULL
server.port=1285
spring.profiles.active=dev

View File

@ -36,8 +36,8 @@ public class AssignmentsControllerTest extends AbstractControllerTest {
@Test
public void shouldReturnOk() throws Exception {
this.service.save(new User(null, null, TEST_MAIL, UserRoles.TEST_USER));
final String token = this.service.login(TEST_MAIL);
final User newuser = this.service.save(new User(null, null, TEST_MAIL, UserRoles.TEST_USER));
final String token = this.service.login(newuser);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(get(ASSIGFNMENTS_ENDPOINT).header("Authorization", "Bearer " + token))

View File

@ -57,7 +57,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldFailedAddingCommisionDueToNoArgs() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_STUDENT_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT).header("Authorization", "Bearer " + token))
@ -67,7 +68,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldReturnOkAddingCommision() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_STUDENT_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT).header("Authorization", "Bearer " + token)
@ -83,7 +85,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldReturnOkGettingAllCommisions() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_STUDENT_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(get(GET_COMMISIONS_ENDPOINT).header("Authorization", "Bearer " + token))
@ -93,7 +96,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldAddCommisionWithSelfIdPrivided() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_STUDENT_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT + "/" + CommisionControllerTest.user.getId().toString())
@ -105,7 +109,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
public void shouldFailCommisionWithSomeoneIdPrividedAsStudent() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_STUDENT_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT + "/" + CommisionControllerTest.otherUser.getId().toString())
@ -116,7 +121,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldFailCommisionAsDeanaryWithNoId() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_DEANERY_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_DEANERY_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT).header("Authorization", "Bearer " + token)
@ -125,8 +131,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldFailCommisionWithSelfIdPrividedAsDeanary() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_DEANERY_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_DEANERY_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT + "/" + CommisionControllerTest.asker.getId().toString())
@ -138,7 +144,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
public void shouldAddCommisionWithSomeoneIdPrividedAsDeanary() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_DEANERY_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_DEANERY_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT + "/" + CommisionControllerTest.otherUser.getId().toString())
@ -150,7 +157,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
public void shouldFailCommisionWithOtherDeanaryIdPrividedAsDeanary() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_DEANERY_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_DEANERY_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(post(ADD_COMMISION_ENDPOINT + "/" + CommisionControllerTest.otherAsker.getId().toString())
@ -162,7 +170,8 @@ public class CommisionControllerTest extends AbstractControllerTest {
public void shouldGetStudentCommisionsListByDeanary() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_DEANERY_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_DEANERY_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(get(GET_SOMEONE_COMMISIONS_ENDPOINT + "/" + CommisionControllerTest.user.getId().toString())
@ -172,8 +181,9 @@ public class CommisionControllerTest extends AbstractControllerTest {
@Test
public void shouldFailStudentCommisionsListByOtherStudent() throws Exception {
this.checkUsers();
final String token = this.service.login(TEST_COMMISIONS_STUDENT_EMAIL);
final User user = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null);
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(get(GET_SOMEONE_COMMISIONS_ENDPOINT + "/" + CommisionControllerTest.user.getId().toString())

View File

@ -45,12 +45,11 @@ public class ConfigControllerTest extends AbstractControllerTest {
@Test
public void shouldReturnOKAuthorized() throws Exception {
final String mail = "shouldReturnOKAuthorized@ConfigController.test";
final User usr = new User(null, null, mail, UserRoles.ADMIN);
this.service.save(usr);
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(mail);
final String token = this.service.login(usr);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(multipart(CONFIG_ENDPOINT).file(file).header("Authorization", "Bearer " + token))
@ -61,12 +60,11 @@ public class ConfigControllerTest extends AbstractControllerTest {
@Test
public void shouldReturnDenyNoAdminAuthorized() throws Exception {
final String mail = "shouldReturnDenyNoAdminAuthorized@ConfigController.test";
final User usr = new User(null, null, mail, UserRoles.TEST_USER);
this.service.save(usr);
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(mail);
final String token = this.service.login(usr);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(multipart(CONFIG_ENDPOINT).file(file).header("Authorization", "Bearer " + token))

View File

@ -30,8 +30,8 @@ public class UsersControllerTest extends AbstractControllerTest {
@Test
public void shouldRestrun200OK() throws Exception {
final String email = "notexistingassignmentuser@shouldRestrun200OK.test";
this.service.save(new User(null, null, email, UserRoles.DEANERY));
final String token = this.service.login(email);
final User user = this.service.save(new User(null, null, email, UserRoles.DEANERY));
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(get(ENDPOINT).param("query", "").header("Authorization", "Bearer " + token))
@ -47,8 +47,8 @@ public class UsersControllerTest extends AbstractControllerTest {
@Test
public void shouldFailedDueToMissingParam() throws Exception {
final String email = "notexistingassignmentuser@shouldFailedDueToMissingParam.test";
this.service.save(new User(null, null, email, UserRoles.DEANERY));
final String token = this.service.login(email);
final User user = this.service.save(new User(null, null, email, UserRoles.DEANERY));
final String token = this.service.login(user);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build();
mockMvc.perform(get(ENDPOINT).header("Authorization", "Bearer " + token))

View File

@ -0,0 +1,20 @@
package com.plannaplan.security.cas;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
public class CustomUAMCasValidatorTest {
@Value("${plannaplan.frontendUrl}")
private String serviceUrl;
@Test
public void shouldValidateWithDomain() {
CustomUAMCasValidator validator = new CustomUAMCasValidator(serviceUrl, "ST-54649-5x4h09vzUpEIyAGmf1sz-cas.amu.edu.pl");
validator.validate();
}
}

View File

@ -1,18 +1,23 @@
package com.plannaplan.security;
package com.plannaplan.security.cas;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
public class CasValidatorTest {
public class DefaultUAMCasValidatorTest {
@Value("${plannaplan.frontendUrl}")
private String serviceUrl;
@Test
@Ignore
public void shouldValidateTicket() {
// you need to privide fresh ticket to make this test pass that's why it is
// marked as ignored
final CasValidator validator = new CasValidator("http://localhost:3000",
final DefaultUAMCasValidator validator = new DefaultUAMCasValidator(serviceUrl,
"ST-572267-cbgKrcJLd0tdCubeLqdW-cas.amu.edu.pl");
try {
System.out.println(validator.validate());
@ -24,9 +29,9 @@ public class CasValidatorTest {
@Test
public void shouldNotValidateTicket() {
final CasValidator validator = new CasValidator("http://localhost:3000", "notticket");
final DefaultUAMCasValidator validator = new DefaultUAMCasValidator(serviceUrl, "notticket");
try {
assertTrue(validator.validate().trim().equals(""));
assertTrue(validator.validate().getEmail().trim().equals(""));
} catch (CasValidationExcepiton e) {
assertTrue(true);
} catch (Exception e) {