Compare commits

..

No commits in common. "eeef96ffb69999b0f0b4cae28d56390f4df13e84" and "bfbcd5c44b3247146ae7541b7048d5ec059f5b50" have entirely different histories.

15 changed files with 162 additions and 370 deletions

View File

@ -17,17 +17,6 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Spring security
//implementation 'org.springframework.boot:spring-boot-starter-security'
//implementation 'org.springframework.security:spring-security-test'
// JSON web token
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2',
// Uncomment the next line if you want to use RSASSA-PSS (PS256, PS384, PS512) algorithms:
//'org.bouncycastle:bcprov-jdk15on:1.60',
'io.jsonwebtoken:jjwt-jackson:0.11.2' // or 'io.jsonwebtoken:jjwt-gson:0.11.2' for gson
}
test {

View File

@ -1,4 +1,4 @@
package com.vpr.server.data;
package com.vpr.server;
import java.sql.Date;
import java.sql.Time;

View File

@ -1,4 +1,4 @@
package com.vpr.server.data;
package com.vpr.server;
import javax.persistence.*;
import java.sql.Time;

View File

@ -1,11 +1,11 @@
package com.vpr.server.repository;
package com.vpr.server;
import com.vpr.server.data.Event;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import javax.transaction.Transactional;
import java.util.List;
// This will be AUTO IMPLEMENTED by Spring into a Bean called eventRepository
// CRUD refers Create, Read, Update, Delete

View File

@ -0,0 +1,141 @@
package com.vpr.server;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.sql.Date;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Optional;
@Controller // This means that this class is a Controller
@RequestMapping(path="/vpr") // This means URL's start with /demo (after Application path)
public class MainController {
// This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
@Autowired
private com.vpr.server.UserRepository userRepository;
@Autowired
private EventRepository eventRepository;
@Autowired
private UserEventRepository userEventRepository;
// POST-request at /add with request parameter
// @ResponseBody means the returned String is the response, not a view name
@PostMapping(path="/add-user")
public @ResponseBody String addNewUser (
@RequestParam String name,
@RequestParam String forename,
@RequestParam String password,
@RequestParam String isAdmin
) {
com.vpr.server.User user = new com.vpr.server.User();
// TODO set correct token and password
user.setName(name);
user.setForename(forename);
user.setPassword(password);
user.setToken("test");
user.setAdmin(isAdmin.equals("1"));
userRepository.save(user);
return "Saved";
}
@PostMapping(path="/add-event")
public @ResponseBody String addEvent (
@RequestParam Integer userId,
@RequestParam String date,
@RequestParam String name,
@RequestParam String start,
@RequestParam String end,
@RequestParam Integer prority,
@RequestParam Boolean isFullDay,
@RequestParam Boolean isPrivate
) {
com.vpr.server.Event event = new com.vpr.server.Event();
event.setName(name);
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm");
long ms = simpleDateFormat.parse(start).getTime();
event.setStart(new Time(ms));
}catch (Exception e){
event.setStart(null);
}
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm");
long ms = simpleDateFormat.parse(end).getTime();
event.setEnd(new Time(ms));
}catch (Exception e){
event.setEnd(null);
}
event.setPriority(prority);
event.setFullDay(isFullDay);
event.setPrivate(isPrivate);
eventRepository.save(event);
com.vpr.server.UserEvent userEvent = new com.vpr.server.UserEvent();
try {
System.out.println("date " + date);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
userEvent.setDate(new java.sql.Date(simpleDateFormat.parse(date).getTime()));
}catch (Exception e){
System.out.println("DATE FORMAT NOT CORRECT");
}
userEvent.setEvent(event);
long uId = Long.valueOf(userId);
User user = userRepository.findById(uId);
userEvent.setUser(user);
System.out.println(userEvent);
System.out.println(user);
userEventRepository.save(userEvent);
return "Saved";
}
@PostMapping(path="/del-event")
public @ResponseBody String addEvent ( @RequestParam Integer eventId ) {
eventRepository.deleteUserEventsById(Long.valueOf(eventId));
eventRepository.deleteById(Long.valueOf(eventId));
return "Deleted";
}
// GET-request at /all-users
// returns JSON-data
@GetMapping(path="/all-users")
public @ResponseBody Object[] getAllUsers() {
return userRepository.findAllUsernames();
}
// POST-request at /all-events
// returns JSON-data
@PostMapping(path="/all-events")
public @ResponseBody Object[] getAllEvents(@RequestParam long userId) {
return eventRepository.findAllVisibleByUserId(userId);
}
@GetMapping(path="/all-events-test")
public @ResponseBody Iterable<com.vpr.server.Event> getAllEventsTest() {
return eventRepository.findAll();
}
}

View File

@ -1,4 +1,4 @@
package com.vpr.server.data;
package com.vpr.server;
import javax.persistence.*;
import java.util.List;
@ -17,14 +17,8 @@ public class User {
@Column(name="forename", nullable=false)
private String forename;
@Column(name="login", nullable=false)
private String login;
@Column(name="password", nullable=false)
private byte[] password;
@Column(name="salt", nullable=false)
private byte[] salt;
private String password;
@Column(name="token")
private String token;
@ -63,30 +57,14 @@ public class User {
this.forename = forename;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public byte[] getPassword() {
public String getPassword() {
return password;
}
public void setPassword(byte[] password) {
public void setPassword(String password) {
this.password = password;
}
public byte[] getSalt() {
return salt;
}
public void setSalt(byte[] salt) {
this.salt = salt;
}
public String getToken() {
return token;
}

View File

@ -1,7 +1,8 @@
package com.vpr.server.data;
package com.vpr.server;
import javax.persistence.*;
import java.sql.Date;
import java.util.List;
// @Entity creates a table out of this class with Hibernate
// @Table defines the table-name

View File

@ -1,4 +1,4 @@
package com.vpr.server.data;
package com.vpr.server;
import java.io.Serializable;
import java.sql.Date;

View File

@ -1,8 +1,11 @@
package com.vpr.server.repository;
package com.vpr.server;
import com.vpr.server.data.UserEvent;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.sql.Date;
import java.util.List;
// This will be AUTO IMPLEMENTED by Spring into a Bean called eventListRepository
// CRUD refers Create, Read, Update, Delete

View File

@ -1,11 +1,13 @@
package com.vpr.server.repository;
package com.vpr.server;
import com.vpr.server.data.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface UserRepository extends CrudRepository<User, Integer> {
@Query(value = "SELECT u.id, u.name, u.forename " +
@ -13,11 +15,5 @@ public interface UserRepository extends CrudRepository<User, Integer> {
nativeQuery = true)
Object[] findAllUsernames();
User findById(long id);
User findByLogin(String login);
User findByLoginAndPassword(String login, byte[] password);
void deleteById(long id);
com.vpr.server.User findById(long id);
}

View File

@ -1,117 +0,0 @@
package com.vpr.server.controller;
import com.vpr.server.data.Event;
import com.vpr.server.data.User;
import com.vpr.server.data.UserEvent;
import com.vpr.server.repository.EventRepository;
import com.vpr.server.repository.UserEventRepository;
import com.vpr.server.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ResponseStatusException;
import java.sql.Time;
import java.text.SimpleDateFormat;
@Controller
@RequestMapping(path = "/event")
public class EventController {
@Autowired
private UserRepository userRepository;
@Autowired
private EventRepository eventRepository;
@Autowired
private UserEventRepository userEventRepository;
/******************
* POST-ENDPOINTS *
******************/
@PostMapping(path = "/add")
public @ResponseBody
String addEvent(
@RequestParam Integer userId,
@RequestParam String date,
@RequestParam String name,
@RequestParam String start,
@RequestParam String end,
@RequestParam Integer prority,
@RequestParam Boolean isFullDay,
@RequestParam Boolean isPrivate
) {
String errorString = "";
Event event = new Event();
System.out.println(name.length() + ". name " + name);
if (name.length() > 3) {
event.setName(name);
} else {
System.out.println("NAME IST ZU KURZ");
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Format nicht korrekt");
}
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm");
long ms = simpleDateFormat.parse(start).getTime();
event.setStart(new Time(ms));
} catch (Exception e) {
event.setStart(null);
}
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm");
long ms = simpleDateFormat.parse(end).getTime();
event.setEnd(new Time(ms));
} catch (Exception e) {
event.setEnd(null);
}
event.setPriority(prority);
event.setFullDay(isFullDay);
event.setPrivate(isPrivate);
UserEvent userEvent = new UserEvent();
try {
System.out.println("date " + date);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
userEvent.setDate(new java.sql.Date(simpleDateFormat.parse(date).getTime()));
} catch (Exception e) {
System.out.println("DATE FORMAT NOT CORRECT");
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Format nicht korrekt");
}
userEvent.setEvent(event);
long uId = Long.valueOf(userId);
User user = userRepository.findById(uId);
userEvent.setUser(user);
System.out.println(userEvent);
System.out.println(user);
eventRepository.save(event);
userEventRepository.save(userEvent);
return "";
}
@PostMapping(path = "/del")
public @ResponseBody
String addEvent(@RequestParam Integer eventId) {
eventRepository.deleteUserEventsById(Long.valueOf(eventId));
eventRepository.deleteById(Long.valueOf(eventId));
return "Deleted";
}
@PostMapping(path = "/all")
public @ResponseBody
Object[] getAllEvents(@RequestParam long userId) {
return eventRepository.findAllVisibleByUserId(userId);
}
}

View File

@ -1,36 +0,0 @@
package com.vpr.server.controller;
import com.vpr.server.data.Event;
import com.vpr.server.data.User;
import com.vpr.server.data.UserEvent;
import com.vpr.server.repository.EventRepository;
import com.vpr.server.repository.UserEventRepository;
import com.vpr.server.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import java.sql.Time;
import java.text.SimpleDateFormat;
@Controller // This means that this class is a Controller
@RequestMapping(path = "/vpr") // This means URL's start with /demo (after Application path)
public class MainController {
// This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
@Autowired
private UserRepository userRepository;
@Autowired
private EventRepository eventRepository;
@Autowired
private UserEventRepository userEventRepository;
@GetMapping(path = "/status-test")
public String statusTest(){
throw new ResponseStatusException(HttpStatus.I_AM_A_TEAPOT, "TestTestTest");
}
}

View File

@ -1,109 +0,0 @@
package com.vpr.server.controller;
import com.vpr.server.data.User;
import com.vpr.server.repository.UserRepository;
import com.vpr.server.security.Hasher;
import com.vpr.server.security.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
@Controller
@RequestMapping(path = "/user")
public class UserController {
@Autowired
private UserRepository userRepository;
/******************
* POST-ENDPOINTS *
******************/
@PostMapping(path = "/add")
public @ResponseBody
String addNewUser(
@RequestParam String name,
@RequestParam String forename,
@RequestParam String login,
@RequestParam String password,
@RequestParam String isAdmin
) {
byte[] salt = Hasher.GenerateSalt();
byte[] hash;
try {
hash = Hasher.HashPassword(password, salt);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Fehler beim hashen");
}
User user = new User();
// TODO set correct token and password
user.setName(name);
user.setForename(forename);
user.setLogin(login);
user.setPassword(hash);
user.setSalt(salt);
user.setToken("test");
user.setAdmin(isAdmin.equals("1"));
userRepository.save(user);
return "" + user.getId();
}
@PostMapping(path = "/login")
public @ResponseBody
String login(
@RequestParam String login,
@RequestParam String password
) {
System.out.println("LOGIN");
User user = userRepository.findByLogin(login);
if (user == null) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Falscher login");
}
byte[] salt = user.getSalt();
byte[] hash;
try {
hash = Hasher.HashPassword(password, salt);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Fehler beim hashen");
}
if (Arrays.equals(user.getPassword(), hash)) {
System.out.println(user.getLogin() + " is now logged in.");
System.out.println(Token.Generate(user.getLogin()));
System.out.println(Token.Verify(Token.Generate(user.getLogin()), user.getLogin()));
return "" + user.getId();
}
System.out.println(user.getLogin() + " failed to logged in.");
System.out.println("entered : " + javax.xml.bind.DatatypeConverter.printHexBinary(hash));
System.out.println("required: " + javax.xml.bind.DatatypeConverter.printHexBinary(user.getPassword()));
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Falscher login");
}
@PostMapping(path = "/del")
public @ResponseBody String deleteUser(@RequestParam Integer userId) {
userRepository.deleteById(Long.valueOf(userId));
return "Deleted";
}
/*****************
* GET-ENDPOINTS *
*****************/
@GetMapping(path = "/all")
public @ResponseBody
Object[] getAllUsers() {
return userRepository.findAllUsernames();
}
}

View File

@ -1,28 +0,0 @@
package com.vpr.server.security;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
public class Hasher {
public static byte[] HashPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
// Credit: https://www.baeldung.com/java-password-hashing
// Generate hash with PBKDF2
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return factory.generateSecret(spec).getEncoded();
}
public static byte[] GenerateSalt(){
// Credit: https://www.baeldung.com/java-password-hashing
// Create a salt
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return salt;
}
}

View File

@ -1,26 +0,0 @@
package com.vpr.server.security;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
public class Token {
private static Key KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);
public static String Generate(String subject){
return Jwts.builder().setSubject(subject).signWith(KEY).compact();
}
public static boolean Verify(String jws, String subject){
try {
assert Jwts.parserBuilder().setSigningKey(KEY).build().parseClaimsJws(jws)
.getBody().getSubject().equals(subject);
return true;
} catch (JwtException e) {
return false;
}
}
}