Merge pull request 'api-service' (#38) from api-service into master
Reviewed-on: http://git.plannaplan.pl/filipizydorczyk/backend/pulls/38
This commit is contained in:
commit
3bce1f91ec
3
.gitignore
vendored
3
.gitignore
vendored
@ -37,3 +37,6 @@ __pycache__
|
|||||||
|
|
||||||
### Parser ###
|
### Parser ###
|
||||||
parser/
|
parser/
|
||||||
|
|
||||||
|
|
||||||
|
envs.sh
|
47
README.md
47
README.md
@ -1,4 +1,4 @@
|
|||||||
## Start aplikacji
|
# Start aplikacji
|
||||||
|
|
||||||
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`
|
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`
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ cd restservice
|
|||||||
mvn spring-boot:run
|
mvn spring-boot:run
|
||||||
```
|
```
|
||||||
|
|
||||||
## Token obtaining
|
# 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
|
Ż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
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ 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.
|
Na koniec w przęglądarce dostaniesz w odpowiedzi token. W samym pliku można zmienić porty aplikacji jeśli to potrzebne.
|
||||||
|
|
||||||
## Profiles
|
# Profiles
|
||||||
|
|
||||||
W aplikacji posiadamy dwa profile. `dev` i `prod`. **Dev** używamy do testowania aplikacji lokalnie. **Pord** służy do stworzenia builda na produkcję.
|
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ę
|
Profil wybieramy w pliku `restservice/src/main/resources/application.properties` wpisując odpowiednią nazwę
|
||||||
@ -45,8 +45,12 @@ W paczce dla proda w protpertiesach poufne dane odczytywane są ze zmiennych śr
|
|||||||
- `PLANNAPLAN_EMAIL_USERNAME` - login naszego maila
|
- `PLANNAPLAN_EMAIL_USERNAME` - login naszego maila
|
||||||
- `PLANNAPLAN_EMAIL_PASSWORD` - hasło naszego maila
|
- `PLANNAPLAN_EMAIL_PASSWORD` - hasło naszego maila
|
||||||
- `PLANNAPLAN_EMAIL` - nasz adres maila
|
- `PLANNAPLAN_EMAIL` - nasz adres maila
|
||||||
|
- `PLANNAPLAN_CONSUMER_KEY` - nasz klucz do usos api
|
||||||
|
- `PLANNAPLAN_CONSUMER_SECRET` - secret naszego klucza
|
||||||
|
|
||||||
## Packaging
|
Należy też pamiętać, że zmienne `PLANNAPLAN_CONSUMER_KEY` oraz `PLANNAPLAN_CONSUMER_SECRET` są potrzebne również w profilu `dev` więc trzeba je dodać w celu tesotowania do zmiennych we własnym systemie
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
@ -56,23 +60,23 @@ mvn clean; 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)
|
||||||
|
|
||||||
## Generowanie dokumentacji
|
# Generowanie dokumentacji
|
||||||
|
|
||||||
### Javadocs
|
## Javadocs
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mvn javadoc:javadoc
|
mvn javadoc:javadoc
|
||||||
```
|
```
|
||||||
|
|
||||||
### Api docs
|
## Api docs
|
||||||
|
|
||||||
Żeby zobaczyć dokumentację api trzeba wejść w przeglądarce na `http://localhost:1285/swagger-ui.html` po odpaleniu aplikacji.
|
Żeby zobaczyć dokumentację api trzeba wejść w przeglądarce na `http://localhost:1285/swagger-ui.html` po odpaleniu aplikacji.
|
||||||
|
|
||||||
#### Nazewnictwo odpowiedzi
|
### 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`
|
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
|
# 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
|
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
|
||||||
|
|
||||||
@ -80,3 +84,28 @@ Spring chyba cacheuje jakies dane dotyczace polaczenia wiec jesli spring wywali
|
|||||||
mvn clean
|
mvn clean
|
||||||
mvn install
|
mvn install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Jeżeli używasz VSCode i testy, które wymagają podanych zmiennych środowiskowych (testy odpytywania usos api) trzeba podać te zmienne w pliku `.vscode/settings.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"files.exclude": {
|
||||||
|
"**/.classpath": true,
|
||||||
|
"**/.project": true,
|
||||||
|
"**/.settings": true,
|
||||||
|
"**/.factorypath": true
|
||||||
|
},
|
||||||
|
"java.configuration.updateBuildConfiguration": "disabled",
|
||||||
|
"java.format.settings.url": "eclipse-formatter.xml",
|
||||||
|
"java.test.config": [
|
||||||
|
{
|
||||||
|
"name": "myConfiguration",
|
||||||
|
"workingDirectory": "${workspaceFolder}",
|
||||||
|
"env": {
|
||||||
|
"PLANNAPLAN_CONSUMER_KEY": "value",
|
||||||
|
"PLANNAPLAN_CONSUMER_SECRET": "value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -74,6 +74,31 @@
|
|||||||
<version>2.2.5.RELEASE</version>
|
<version>2.2.5.RELEASE</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework.social/spring-social-core -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.5.12</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.scribejava</groupId>
|
||||||
|
<artifactId>scribejava-core</artifactId>
|
||||||
|
<version>8.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.9.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -4,6 +4,21 @@
|
|||||||
"name": "plannaplan.email",
|
"name": "plannaplan.email",
|
||||||
"type": "java.lang.String",
|
"type": "java.lang.String",
|
||||||
"description": "Email from which app sends message"
|
"description": "Email from which app sends message"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "plannaplan.apiurl",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "Url to usos api endpoints"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "plannaplan.apikey",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "Api consumer key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "plannaplan.apisecret",
|
||||||
|
"type": "java.lang.String",
|
||||||
|
"description": "Api consumer secret"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
61
buisnesslogic/src/main/java/com/plannaplan/api/UsosOauth1Service.java
Executable file
61
buisnesslogic/src/main/java/com/plannaplan/api/UsosOauth1Service.java
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
package com.plannaplan.api;
|
||||||
|
|
||||||
|
import com.github.scribejava.core.builder.api.DefaultApi10a;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* singleton class to sign usos api requests with oauth
|
||||||
|
*/
|
||||||
|
public class UsosOauth1Service extends DefaultApi10a {
|
||||||
|
|
||||||
|
private static final String AUTHORIZE_URL = "https://usosapidemo.amu.edu.pl/services/oauth/authorize";
|
||||||
|
private static final String REQUEST_TOKEN_URL = "https://usosapidemo.amu.edu.pl/services/oauth/request_token";
|
||||||
|
|
||||||
|
private final String scopesAsString;
|
||||||
|
|
||||||
|
protected UsosOauth1Service() {
|
||||||
|
scopesAsString = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UsosOauth1Service(String... scopes) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
for (String scope : scopes) {
|
||||||
|
builder.append('+').append(scope);
|
||||||
|
}
|
||||||
|
scopesAsString = "?scope=" + builder.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class InstanceHolder {
|
||||||
|
|
||||||
|
private static final UsosOauth1Service INSTANCE = new UsosOauth1Service();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UsosOauth1Service instance() {
|
||||||
|
return InstanceHolder.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get instance withj scopes
|
||||||
|
*
|
||||||
|
* @param scopes to get instance with
|
||||||
|
* @return UsosOauth1Service instance
|
||||||
|
*/
|
||||||
|
public static UsosOauth1Service instance(String... scopes) {
|
||||||
|
return scopes == null || scopes.length == 0 ? instance() : new UsosOauth1Service(scopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRequestTokenEndpoint() {
|
||||||
|
return scopesAsString == null ? REQUEST_TOKEN_URL : REQUEST_TOKEN_URL + scopesAsString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessTokenEndpoint() {
|
||||||
|
return "https://usosapidemo.amu.edu.pl/services/oauth/access_token";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getAuthorizationBaseUrl() {
|
||||||
|
return AUTHORIZE_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,7 +8,8 @@ import javax.persistence.JoinColumn;
|
|||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity of Assignment grouping of state associated about group_id and commision_id
|
* Entity of Assignment grouping of state associated about group_id and
|
||||||
|
* commision_id
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ public class Assignment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Assignment
|
* Assignment
|
||||||
|
*
|
||||||
* @param group group we would like to assign
|
* @param group group we would like to assign
|
||||||
* @param commision commision that assignment belongs to
|
* @param commision commision that assignment belongs to
|
||||||
* @param isPastAssignment is assignment past or no
|
* @param isPastAssignment is assignment past or no
|
||||||
@ -38,6 +40,7 @@ public class Assignment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Assignment
|
* Assignment
|
||||||
|
*
|
||||||
* @param group group we would like to assign
|
* @param group group we would like to assign
|
||||||
* @param commision commision that assignment belongs to
|
* @param commision commision that assignment belongs to
|
||||||
*/
|
*/
|
||||||
@ -50,6 +53,7 @@ public class Assignment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Id getter
|
* Id getter
|
||||||
|
*
|
||||||
* @return id id of assignment
|
* @return id id of assignment
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -68,6 +72,7 @@ public class Assignment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* isPastAssignment getter
|
* isPastAssignment getter
|
||||||
|
*
|
||||||
* @return isPastAssignment
|
* @return isPastAssignment
|
||||||
*/
|
*/
|
||||||
public boolean isPastAssignment() {
|
public boolean isPastAssignment() {
|
||||||
@ -76,7 +81,8 @@ public class Assignment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* setter isPastAssignment
|
* setter isPastAssignment
|
||||||
* @param isPastAssignment
|
*
|
||||||
|
* @param isPastAssignment is assignment past or not
|
||||||
*/
|
*/
|
||||||
public void setPastAssignment(boolean isPastAssignment) {
|
public void setPastAssignment(boolean isPastAssignment) {
|
||||||
this.isPastAssignment = isPastAssignment;
|
this.isPastAssignment = isPastAssignment;
|
||||||
|
@ -56,7 +56,6 @@ public class Groups {
|
|||||||
this.zajCykId = zajCykId;
|
this.zajCykId = zajCykId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groups
|
* Groups
|
||||||
*
|
*
|
||||||
@ -90,9 +89,10 @@ public class Groups {
|
|||||||
* @param day day given to the groups
|
* @param day day given to the groups
|
||||||
* @param lecturer lecturer given to the groups
|
* @param lecturer lecturer given to the groups
|
||||||
* @param zajCykId number of class in the term
|
* @param zajCykId number of class in the term
|
||||||
* @param gr_nr Number of class/course
|
* @param grNr Number of class/course
|
||||||
*/
|
*/
|
||||||
public Groups(int capacity, String room, Course course, int time, int endTime, WeekDay day, Lecturer lecturer, Integer zajCykId, Integer grNr) {
|
public Groups(int capacity, String room, Course course, int time, int endTime, WeekDay day, Lecturer lecturer,
|
||||||
|
Integer zajCykId, Integer grNr) {
|
||||||
this(capacity, room, course, time, endTime, day, lecturer);
|
this(capacity, room, course, time, endTime, day, lecturer);
|
||||||
this.zajCykId = zajCykId;
|
this.zajCykId = zajCykId;
|
||||||
this.grNr = grNr;
|
this.grNr = grNr;
|
||||||
@ -110,7 +110,8 @@ public class Groups {
|
|||||||
* @param zajCykId number of class in the term
|
* @param zajCykId number of class in the term
|
||||||
* @param grNr Number of class/course
|
* @param grNr Number of class/course
|
||||||
*/
|
*/
|
||||||
public Groups(int capacity, String room, Course course, int time, WeekDay day, Lecturer lecturer, Integer zajCykId, Integer grNr) {
|
public Groups(int capacity, String room, Course course, int time, WeekDay day, Lecturer lecturer, Integer zajCykId,
|
||||||
|
Integer grNr) {
|
||||||
this(capacity, room, course, time, time + DEFAULT_CLASS_TIME, day, lecturer);
|
this(capacity, room, course, time, time + DEFAULT_CLASS_TIME, day, lecturer);
|
||||||
this.zajCykId = zajCykId;
|
this.zajCykId = zajCykId;
|
||||||
this.grNr = grNr;
|
this.grNr = grNr;
|
||||||
@ -141,7 +142,8 @@ public class Groups {
|
|||||||
* @param day day given to the groups
|
* @param day day given to the groups
|
||||||
* @param lecturer lecturer given to the groups
|
* @param lecturer lecturer given to the groups
|
||||||
*/
|
*/
|
||||||
public void update(Integer capacity, String room, Course course, Integer time, Integer endTime, WeekDay day, Lecturer lecturer){
|
public void update(Integer capacity, String room, Course course, Integer time, Integer endTime, WeekDay day,
|
||||||
|
Lecturer lecturer) {
|
||||||
if (capacity != null) {
|
if (capacity != null) {
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import javax.persistence.GeneratedValue;
|
|||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import com.plannaplan.models.UserApiResponse;
|
||||||
import com.plannaplan.types.UserRoles;
|
import com.plannaplan.types.UserRoles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +41,7 @@ public class 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 mail mail given to the user
|
* @param mail mail given to the user
|
||||||
* @param role
|
* @param role user's 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;
|
||||||
@ -55,7 +56,7 @@ public class User {
|
|||||||
* @param surname surname given to the user
|
* @param surname surname given to the user
|
||||||
* @param mail 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
|
* @param role user's 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);
|
||||||
@ -188,6 +189,16 @@ public class User {
|
|||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates user entity with data got by UsosApiService::getUserData
|
||||||
|
*
|
||||||
|
* @param usosData UserApiResponse model with needed data
|
||||||
|
*/
|
||||||
|
public void updateWithUsosData(UserApiResponse usosData) {
|
||||||
|
this.name = usosData.getName();
|
||||||
|
this.surname = usosData.getSurname();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* it checks if given ammount of time passed since last token usage. If not
|
* it checks if given ammount of time passed since last token usage. If not
|
||||||
* retunr true and reset time otherwise return false and token won work anymore
|
* retunr true and reset time otherwise return false and token won work anymore
|
||||||
|
29
buisnesslogic/src/main/java/com/plannaplan/models/UserApiResponse.java
Executable file
29
buisnesslogic/src/main/java/com/plannaplan/models/UserApiResponse.java
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
package com.plannaplan.models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model to keep data from /services/users/user response called in
|
||||||
|
* UsosApiService
|
||||||
|
*/
|
||||||
|
public class UserApiResponse {
|
||||||
|
private String name;
|
||||||
|
private String surname;
|
||||||
|
|
||||||
|
public UserApiResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -36,6 +36,12 @@ import org.springframework.stereotype.Repository;
|
|||||||
@Repository
|
@Repository
|
||||||
public interface UserRepository extends JpaRepository<User, Long> {
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
@Query("FROM User WHERE email = ?1 OR usosId = ?1")
|
@Query("FROM User WHERE email = ?1 OR usosId = ?1")
|
||||||
|
/**
|
||||||
|
* return user by given authority
|
||||||
|
*
|
||||||
|
* @param authority user usosId or email
|
||||||
|
* @return optional with user if found
|
||||||
|
*/
|
||||||
Optional<User> getByAuthority(@Param("authority") String authority);
|
Optional<User> getByAuthority(@Param("authority") String authority);
|
||||||
|
|
||||||
@Query("FROM User WHERE email = ?1")
|
@Query("FROM User WHERE email = ?1")
|
||||||
@ -51,6 +57,13 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
|||||||
List<User> searchForUsers(@Param("query") String query);
|
List<User> searchForUsers(@Param("query") String query);
|
||||||
|
|
||||||
@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")
|
||||||
|
/**
|
||||||
|
* search for user with given query
|
||||||
|
*
|
||||||
|
* @param query string that will be matched to users name and surname
|
||||||
|
* @param role limits results by role
|
||||||
|
* @return list opf results
|
||||||
|
*/
|
||||||
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")
|
@Query("FROM User WHERE role=?1")
|
||||||
|
@ -67,9 +67,9 @@ public class GroupService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param assingemnts list of assingemnts you want to get taken places ammount
|
* @param assignments list of assignments you want to get taken places ammount
|
||||||
* @return HashMap<Long, Integer> where Long is group id and Integer is how many
|
* @return HashMap of Long to Integer where Long is group id and Integer is how
|
||||||
* places in gorup is already taken
|
* many places in gorup is already taken
|
||||||
*/
|
*/
|
||||||
public HashMap<Long, Integer> getTakenPlacesOfAssignments(List<Assignment> assignments) {
|
public HashMap<Long, Integer> getTakenPlacesOfAssignments(List<Assignment> assignments) {
|
||||||
return getTakenPlaces(assignments.stream().map(Assignment::getGroup).collect(Collectors.toList()));
|
return getTakenPlaces(assignments.stream().map(Assignment::getGroup).collect(Collectors.toList()));
|
||||||
@ -78,8 +78,8 @@ public class GroupService {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param groups list of groups you want to get taken places ammount
|
* @param groups list of groups you want to get taken places ammount
|
||||||
* @return HashMap<Long, Integer> where Long is group id and Integer is how many
|
* @return HashMap of Long to Integer where Long is group id and Integer is how
|
||||||
* places in gorup is already taken
|
* many places in gorup is already taken
|
||||||
*/
|
*/
|
||||||
public HashMap<Long, Integer> getTakenPlaces(List<Groups> groups) {
|
public HashMap<Long, Integer> getTakenPlaces(List<Groups> groups) {
|
||||||
HashMap<Long, Integer> response = new HashMap<>();
|
HashMap<Long, Integer> response = new HashMap<>();
|
||||||
|
@ -6,6 +6,7 @@ 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.models.UserApiResponse;
|
||||||
import com.plannaplan.repositories.UserRepository;
|
import com.plannaplan.repositories.UserRepository;
|
||||||
import com.plannaplan.types.UserRoles;
|
import com.plannaplan.types.UserRoles;
|
||||||
|
|
||||||
@ -20,14 +21,33 @@ public class UserService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository repo;
|
private UserRepository repo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UsosApiService service;
|
||||||
|
|
||||||
public UserService() {
|
public UserService() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if user exist and return him or creates new one with student role
|
||||||
|
* otherwise
|
||||||
|
*
|
||||||
|
* @param email user email in usos
|
||||||
|
* @param usosId user id in usos
|
||||||
|
* @return user entity instace containing changes saved in database
|
||||||
|
*/
|
||||||
public User checkForUser(String email, String usosId) {
|
public User checkForUser(String email, String usosId) {
|
||||||
return this.checkForUser(email, usosId, UserRoles.STUDENT);
|
return this.checkForUser(email, usosId, UserRoles.STUDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if user exist and creates new one if doesn't
|
||||||
|
*
|
||||||
|
* @param email user email in usos
|
||||||
|
* @param usosId user id in usos
|
||||||
|
* @param roleIfNotExist role to be set in case user is not in database yet
|
||||||
|
* @return user entity instace containing changes saved in database
|
||||||
|
*/
|
||||||
public User checkForUser(String email, String usosId, UserRoles roleIfNotExist) {
|
public User checkForUser(String email, String usosId, UserRoles roleIfNotExist) {
|
||||||
if (usosId == null) {
|
if (usosId == null) {
|
||||||
Optional<User> user = this.repo.getByEmail(email.replace("\n", "").trim());
|
Optional<User> user = this.repo.getByEmail(email.replace("\n", "").trim());
|
||||||
@ -48,8 +68,20 @@ public class UserService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generates token for user and if user don't have name in database it will
|
||||||
|
* attemp to obtain these from usos api and saves changes in database
|
||||||
|
*
|
||||||
|
* @param authority user we want to login
|
||||||
|
* @return user with changed values after save in db
|
||||||
|
* @throws UserNotFoundException throwed if user doesn't exist
|
||||||
|
*/
|
||||||
public User login(User authority) throws UserNotFoundException {
|
public User login(User authority) throws UserNotFoundException {
|
||||||
final String token = UUID.randomUUID().toString();
|
final String token = UUID.randomUUID().toString();
|
||||||
|
if ((authority.getName() == null || authority.getSurname() == null) && authority.getUsosId() != null) {
|
||||||
|
final UserApiResponse resp = this.service.getUserData(authority.getUsosId());
|
||||||
|
authority.updateWithUsosData(resp);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
authority.setToken(token);
|
authority.setToken(token);
|
||||||
this.repo.save(authority);
|
this.repo.save(authority);
|
||||||
@ -59,16 +91,34 @@ public class UserService {
|
|||||||
return authority;
|
return authority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sacves user to databse and return instatnce with id
|
||||||
|
*
|
||||||
|
* @param user to be saved
|
||||||
|
* @return instatnce with bd id
|
||||||
|
*/
|
||||||
public User save(User user) {
|
public User save(User user) {
|
||||||
return this.repo.save(user);
|
return this.repo.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param email of user to be find
|
||||||
|
* @return user with given mail
|
||||||
|
* @throws UserNotFoundException throwed if user doesn't exist
|
||||||
|
*/
|
||||||
public User getUserByEmail(String email) throws UserNotFoundException {
|
public User getUserByEmail(String email) throws UserNotFoundException {
|
||||||
return this.repo.getByEmail(email.replace("\n", "").trim())
|
return this.repo.getByEmail(email.replace("\n", "").trim())
|
||||||
.orElseThrow(() -> new UserNotFoundException("Cannot find user with given authority"));
|
.orElseThrow(() -> new UserNotFoundException("Cannot find user with given authority"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return user by given authority
|
||||||
|
*
|
||||||
|
* @param authority user usosId or email
|
||||||
|
* @return optional with user if found
|
||||||
|
*/
|
||||||
public Optional<User> getByAuthority(String authority) {
|
public Optional<User> getByAuthority(String authority) {
|
||||||
return this.repo.getByAuthority(authority);
|
return this.repo.getByAuthority(authority);
|
||||||
}
|
}
|
||||||
@ -77,6 +127,12 @@ public class UserService {
|
|||||||
return this.repo.getByToken(token);
|
return this.repo.getByToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search for user with given query
|
||||||
|
*
|
||||||
|
* @param query string that will be matched to users name and surname
|
||||||
|
* @return list opf results
|
||||||
|
*/
|
||||||
public List<User> searchForStudents(String query) {
|
public List<User> searchForStudents(String query) {
|
||||||
return this.repo.searchForUsers(query, UserRoles.STUDENT);
|
return this.repo.searchForUsers(query, UserRoles.STUDENT);
|
||||||
}
|
}
|
||||||
|
74
buisnesslogic/src/main/java/com/plannaplan/services/UsosApiService.java
Executable file
74
buisnesslogic/src/main/java/com/plannaplan/services/UsosApiService.java
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
package com.plannaplan.services;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
|
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||||
|
import com.github.scribejava.core.model.OAuth1AccessToken;
|
||||||
|
import com.github.scribejava.core.model.OAuthRequest;
|
||||||
|
import com.github.scribejava.core.model.Response;
|
||||||
|
import com.github.scribejava.core.model.Verb;
|
||||||
|
import com.github.scribejava.core.oauth.OAuth10aService;
|
||||||
|
import com.plannaplan.api.UsosOauth1Service;
|
||||||
|
import com.plannaplan.models.UserApiResponse;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* service to call usos api endpoints
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UsosApiService {
|
||||||
|
|
||||||
|
private static final String NAME_FIELD = "first_name";
|
||||||
|
private static final String SURNAME_FIELD = "last_name";
|
||||||
|
|
||||||
|
@Value("${plannaplan.apiurl}")
|
||||||
|
private String apiUrl;
|
||||||
|
|
||||||
|
@Value("${plannaplan.apikey}")
|
||||||
|
private String apikey;
|
||||||
|
|
||||||
|
@Value("${plannaplan.apisecret}")
|
||||||
|
private String apisecret;
|
||||||
|
|
||||||
|
public UsosApiService() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /services/users/user
|
||||||
|
*
|
||||||
|
* @param usosId user id in usos
|
||||||
|
* @return UserApiResponse modle contatining desired values
|
||||||
|
*/
|
||||||
|
public UserApiResponse getUserData(String usosId) {
|
||||||
|
final UserApiResponse apiResponse = new UserApiResponse();
|
||||||
|
try {
|
||||||
|
final OAuth10aService service = new ServiceBuilder(apikey).apiSecret(apisecret)
|
||||||
|
.build(UsosOauth1Service.instance());
|
||||||
|
|
||||||
|
final OAuthRequest request = new OAuthRequest(Verb.GET, apiUrl + "/services/users/user?user_id=" + usosId);
|
||||||
|
service.signRequest(new OAuth1AccessToken("", ""), request);
|
||||||
|
|
||||||
|
try (Response response = service.execute(request)) {
|
||||||
|
final String json = response.getBody();
|
||||||
|
final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
Map<String, String> map = mapper.readValue(json, new TypeReference<Map<String, String>>() {
|
||||||
|
});
|
||||||
|
apiResponse.setName(map.get(NAME_FIELD));
|
||||||
|
apiResponse.setSurname(map.get(SURNAME_FIELD));
|
||||||
|
}
|
||||||
|
} catch (IOException | InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
buisnesslogic/src/test/java/com/plannaplan/services/UsosApiServiceTest.java
Executable file
38
buisnesslogic/src/test/java/com/plannaplan/services/UsosApiServiceTest.java
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
package com.plannaplan.services;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import com.plannaplan.models.UserApiResponse;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
@ContextConfiguration
|
||||||
|
public class UsosApiServiceTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UsosApiService service;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void shouldReturnPersonalData() throws IOException, InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
final UserApiResponse response = this.service.getUserData("499054");
|
||||||
|
|
||||||
|
assertTrue(response.getName().equals("Marcin"));
|
||||||
|
assertTrue(response.getSurname().equals("Woźniak"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,5 +14,8 @@ spring.mail.properties.mail.smtp.auth=false
|
|||||||
spring.mail.properties.mail.smtp.starttls.enable=false
|
spring.mail.properties.mail.smtp.starttls.enable=false
|
||||||
|
|
||||||
plannaplan.email = plannaplan.kontakt@gmail.com
|
plannaplan.email = plannaplan.kontakt@gmail.com
|
||||||
|
plannaplan.apiurl = https://usosapidemo.amu.edu.pl
|
||||||
|
plannaplan.apikey=${PLANNAPLAN_CONSUMER_KEY}
|
||||||
|
plannaplan.apisecret=${PLANNAPLAN_CONSUMER_SECRET}
|
||||||
|
|
||||||
server.port=1285
|
server.port=1285
|
@ -19,3 +19,6 @@ 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
|
plannaplan.email = plannaplan.kontakt@gmail.com
|
||||||
|
plannaplan.apiurl = https://usosapidemo.amu.edu.pl
|
||||||
|
plannaplan.apikey=${PLANNAPLAN_CONSUMER_KEY}
|
||||||
|
plannaplan.apisecret=${PLANNAPLAN_CONSUMER_SECRET}
|
@ -20,6 +20,10 @@ server.port=1285
|
|||||||
plannaplan.email = ${PLANNAPLAN_EMAIL}
|
plannaplan.email = ${PLANNAPLAN_EMAIL}
|
||||||
plannaplan.dev = false
|
plannaplan.dev = false
|
||||||
plannaplan.frontendUrl= https://wmi.plannaplan.pl
|
plannaplan.frontendUrl= https://wmi.plannaplan.pl
|
||||||
|
plannaplan.apiurl = https://usosapidemo.amu.edu.pl
|
||||||
|
plannaplan.apikey=${PLANNAPLAN_CONSUMER_KEY}
|
||||||
|
plannaplan.apisecret=${PLANNAPLAN_CONSUMER_SECRET}
|
||||||
|
|
||||||
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=
|
||||||
|
Loading…
Reference in New Issue
Block a user