This commit is contained in:
Katharina Will 2019-04-09 16:21:53 +02:00
commit 842ca6aa56
24 changed files with 482 additions and 117 deletions

View File

@ -35,7 +35,20 @@ dependencies {
//JSON Parser //JSON Parser
implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.google.code.gson:gson:2.8.5'
//compile 'org.springframework.boot:spring-boot-starter-tomcat'
//compile 'org.springframework.boot:spring-boot-starter-security'
//compile 'org.springframework.boot:spring-boot-starter-actuator'
//compile 'org.springframework.boot:spring-boot-starter-aop'
//ompile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '1.2.0.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-core', version: '5.1.4.RELEASE' compile group: 'org.springframework.security', name: 'spring-security-core', version: '5.1.4.RELEASE'
//compile group: 'at.favre.lib', name: 'bcrypt', version: '{latest-version}'
//JWT
compile 'io.jsonwebtoken:jjwt-api:0.10.5'
runtime 'io.jsonwebtoken:jjwt-impl:0.10.5',
'io.jsonwebtoken:jjwt-jackson:0.10.5'
} }

View File

@ -1,74 +1,182 @@
<template> <template>
<div> <div>
<form> <!-- <div :is="stationComponent" @q-tb="scrollToBottomState" :stationObject="tempStation">STATION</div>-->
<div class="q-pa-md q-gutter-y-md"> <!-- <div v-show="!stationComponent">-->
<p class="text-h5">Cache erstellen/bearbeiten</p> <form>
<q-input class="col" dense stack-label filled v-model="text" label="Name"/> <div class="q-pa-md q-gutter-y-md">
<q-input <p class="text-h5">{{ isNewCache ? "Neuen Cache erstellen" : "Cache bearbeiten"}}</p>
v-model="description" <q-input class="col" dense stack-label filled v-model="tempCache.name" label="Name" @change="cacheToStore"/>
dense <q-input
stack-label v-model="tempCache.description"
filled dense
autogrow stack-label
type="textarea" filled
label="Beschreibung" autogrow
/> type="textarea"
<q-input class="col" dense stack-label filled v-model="text" label="Punktewert"/> label="Beschreibung"
<p class="text-h6">Stationen</p> @change="cacheToStore"
<q-list bordered separator class="rounded-borders" > />
<q-input class="col" dense stack-label filled v-model="tempCache.rankingPoints" label="Punktewert"
@change="cacheToStore"/>
<q-input
v-model="tempCache.reward"
dense
stack-label
filled
autogrow
type="textarea"
label="Belohnung"
@change="cacheToStore"
/>
<p class="text-h6">Stationen</p>
<q-list bordered separator class="rounded-borders">
<q-item> <q-item v-for="(station, index) in cache.stationen" :key="index">
<q-item-section avatar> <q-item-section avatar>
<q-avatar color="primary" text-color="white"> <q-avatar color="primary" text-color="white">
1 {{ index + 1 }}
</q-avatar> </q-avatar>
</q-item-section> </q-item-section>
<q-item-section top> <q-item-section top>
<q-item-label lines="1"> <q-item-label lines="1">
<!--<span class="text-weight-medium">[quasarframework/quasar]</span>--> <span class="text-grey-8">ID: {{ station.id ? station.id : "keine" }}</span>
<span class="text-grey-8">Beschreibung:</span> </q-item-label>
</q-item-label> <q-item-label lines="1" class="q-mt-xs text-body2">
<q-item-label lines="1" class="q-mt-xs text-body2"> <span class="cursor-pointer">{{ station.description }}</span>
<span class="cursor-pointer">Dies ist der Anfang der Beschreibung...</span> </q-item-label>
</q-item-label> <q-item-label caption lines="1">
</q-item-section> Code: {{ station.code }}
</q-item-label>
</q-item-section>
<q-item-section side> <q-item-section side>
<div class="text-grey-8 q-gutter-xs"> <div class="text-grey-8 q-gutter-xs">
<q-btn class="" color="" flat dense round icon="delete" /> <q-btn disable @click="deleteStation" class="" color="" flat dense round icon="delete"/>
<q-btn class="" color="" flat dense round icon="edit" /> <q-btn @click="editStation(index)" class="" color="" flat dense round icon="edit"/>
</div> </div>
</q-item-section> </q-item-section>
</q-item> </q-item>
</q-list> </q-list>
<div class="row reverse"> <div class="row reverse">
<q-btn @click="addStation" unelevated color="primary" label="Station hinzufügen" icon-right="add"/> <q-btn @click="addStation" unelevated color="primary" label="Station hinzufügen" icon-right="add"/>
</div>
<div class="row q-mt-xl">
<q-btn @click="saveCache" class="full-width" unelevated stack color="positive" label="Cache speichern"
icon="save_alt"/>
</div>
</div> </div>
<div class="row q-mt-xl"> </form>
<q-btn @click="saveCache" class="full-width" unelevated stack color="positive" label="Cache speichern" icon="save_alt"/> <!-- </div>-->
</div>
</div>
</form>
</div> </div>
</template> </template>
<script> <script>
// import station from './StationEdit'
import {mapGetters} from 'vuex';
export default { export default {
name: "Cache", name: "Cache",
data() { data() {
return { return {
text: "" // stationComponent: null,
scrolldown: false,
isNewCache: this.$route.params.id === undefined,
tempCache: {},
} }
}, },
// components: {
// station
// },
beforeCreate: function () {
},
created: function () {
console.log("isNewCache: " + this.isNewCache);
console.log("fetch Caches from Store");
this.tempCache = JSON.parse(JSON.stringify(this.cache))
},
beforeMount: function () {
},
mounted: function () {
console.log("Scrolldown: " + this.scrolldown)
},
updated: function () {
if (this.scrolldown) {
console.log("scroll down...");
window.scrollTo(0, document.body.scrollHeight);
this.scrolldown = false
}
//this.SET_CACHE(this.tempCache);
//this.scrollToBottom();
},
methods: { methods: {
// ...mapMutations([
// 'cacheCollector/SET_CACHE',
// 'cacheCollector/ADD_STATION',
// 'cacheCollector/REMOVE_STATION',
// 'cacheCollector/RESET_NEW_CACHE',
// 'cacheCollector/LOAD_REMOTE_CACHE'
// ]),
// swapComponent: function (component) {
// this.stationComponent = component;
// },
cacheToStore() {
// push tempCache to Store
console.log("set Cache");
this.$store.commit('cacheCollector/SET_CACHE', JSON.parse(JSON.stringify(this.tempCache)));
// this.SET_CACHE(JSON.parse(JSON.stringify(this.tempCache)));
},
addStation() { addStation() {
this.$router.push({ path: '/station' });
//this.swapComponent(station);
// create Station and add it to array tempCache.stationen
},
editStation(index) {
console.log("editStation("+index+")");
const station = this.cache.stationen[index];
console.log(station)
if (station.hasOwnProperty('id') ) {
this.$router.push({ path: '/station/'+station.id});
} else {
// TODO Stationen bearbeitbar machen bevor sie abgeschickt werden. Am besten Station Objekt als Übergabe Parameter bei Router
this.$store.commit('cacheCollector/SET_TEMPSTATION', station);
this.$router.push({ path: `/station?local=${index}` }); // add parameter
}
},
deleteStation() {
}, },
saveCache() { saveCache() {
// commit to store, send to api, if success -> reset store
} if (this.isNewCache) {
console.log(this.cache);
console.log(JSON.stringify(this.cache));
this.$axios.post('http://localhost:8080/api/createCache', this.cache)
.then((response) => {
console.log("POST api/createCache: " + response.statusText);
this.$router.push({ path: '/overview' });
})
.catch((error) => {
});
} else {
// TODO update existing Cache
}
},
},
computed: {
...mapGetters({
cache: 'cacheCollector/GET_CACHE'
}),
// computedCache: {
// set(value) {
// console.log("set cache")
// },
// get() {
// console.log("get cache");
// return this.$store.getters.cacheCollector.GET_CACHE
// }
// }
} }
} }
</script> </script>

View File

@ -5,7 +5,7 @@
</p> </p>
<p class="text-faded">Sorry, nothing here...<strong>(404)</strong></p> <p class="text-faded">Sorry, nothing here...<strong>(404)</strong></p>
<q-btn color="secondary" style="width:200px;" @click="$router.push('/')" <q-btn color="secondary" style="width:200px;" @click="$router.push('/')"
>Go back</q-btn >Zur Startseite</q-btn
> >
</div> </div>
</template> </template>

View File

@ -123,11 +123,11 @@
}) })
.then((response) => { .then((response) => {
console.log("GET/POST http://localhost:8080/api/logout/ - response: " + response.data); console.log("GET/POST http://localhost:8080/api/logout/ - response: " + response.data);
localStorage.removeItem('userToken');
this.evalAuthentication();
}) })
.catch((error) => { .catch((error) => {
}); });
localStorage.removeItem('userToken');
this.evalAuthentication();
}, },
}, },
}; };

View File

@ -45,12 +45,15 @@
</q-item> </q-item>
<q-item class="q-pr-sm reverse q-gutter-x-sm"> <q-item class="q-pr-sm reverse q-gutter-x-sm">
<q-btn @click="startCache(cache.id)" unelevated color="positive" stack icon="arrow_forward" label="Starten" size="sm"/> <q-btn @click="startCache(cache.id)" unelevated color="positive" stack icon="arrow_forward" label="Starten" size="sm"/>
<q-btn v-if="hasAdminState" @click="startCache(cache.id)" unelevated color="amber" stack icon="edit" label="Bearbeiten" size="sm"/> <q-btn v-if="hasAdminState" @click="editCache(cache.id)" unelevated color="amber" stack icon="edit" label="Bearbeiten" size="sm"/>
<q-btn v-if="hasAdminState" @click="startCache(cache.id)" unelevated color="negative" stack icon="delete" label="Löschen" size="sm"/> <q-btn v-if="hasAdminState" @click="deleteCache(cache.id)" unelevated color="negative" stack icon="delete" label="Löschen" size="sm"/>
</q-item> </q-item>
</q-expansion-item> </q-expansion-item>
</q-card> </q-card>
</q-list> </q-list>
<div v-if="hasAdminState" class="row">
<q-btn @click="addCache" unelevated color="primary" stack icon="add" label="Neuer Cache" class="full-width"/>
</div>
</q-tab-panel> </q-tab-panel>
@ -108,6 +111,13 @@
this.caches = response.data; this.caches = response.data;
}) })
}, },
addCache() {
this.$router.push({ path: `/cache` })
},
editCache() {
},
removeCache() {
},
startCache(cacheID) { startCache(cacheID) {
const userToken = JSON.parse(localStorage.getItem('userToken')); const userToken = JSON.parse(localStorage.getItem('userToken'));
let params = { cacheID: cacheID }; let params = { cacheID: cacheID };
@ -118,8 +128,9 @@
this.$axios.get('http://localhost:8080/api/startCache', { params }) this.$axios.get('http://localhost:8080/api/startCache', { params })
.then((response) => { .then((response) => {
console.log("Angefangen: " + response.data); console.log(response.data);
let stationID = response.data.aktuelleStation.id; // let stationID = response.data.stationen[0].id;
let stationID = this.caches.find(x => x.id === cacheID).stationen[0].id;
console.log(stationID); console.log(stationID);
this.$router.push({ path: `/station/${stationID}` }) this.$router.push({ path: `/station/${stationID}` })
}) })

View File

@ -28,7 +28,7 @@
<q-input class="col" dense stack-label filled v-model="station.solution" label="Lösung" /> <q-input class="col" dense stack-label filled v-model="station.solution" label="Lösung" />
<q-input class="col q-mt-md" dense stack-label filled v-model="station.code" label="Code" readonly/> <q-input class="col q-mt-md" dense stack-label filled v-model="station.code" label="Code" readonly/>
<div class="row reverse q-mt-md q-gutter-x-md"> <div class="row reverse q-mt-md q-gutter-x-md">
<q-btn @click="addStation" unelevated color="primary" label="Speichern" icon-right="add"/> <q-btn @click="saveStation" unelevated color="primary" label="Speichern" icon-right="add"/>
<q-btn @click="dismiss" unelevated color="negative" label="verwerfen" icon-right="delete"/> <q-btn @click="dismiss" unelevated color="negative" label="verwerfen" icon-right="delete"/>
</div> </div>
@ -36,13 +36,13 @@
</template> </template>
<script> <script>
import {mapGetters} from 'vuex';
export default { export default {
name: "Station", name: "Station",
data() { data() {
return { return {
description: "Rätsel, Aufgabe und Informationen zur Station.", description: "Rätsel, Aufgabe und Informationen zur Station.",
text:"v-model !!",
latlang: "", latlang: "",
station: { station: {
description: "description", description: "description",
@ -51,20 +51,27 @@
solution: "solution", solution: "solution",
code: 357547 code: 357547
}, },
isNewStation: true,
// stationObject: null,
} }
}, },
// props: [ 'stationObject' ],
created: function() { created: function() {
this.station = this.tempStation;
console.log(this.station);
}, },
beforeMount: function() { beforeMount: function() {
}, },
mounted: function() { mounted: function() {
console.log("'id' from url: "+this.$route.params.id); this.isNewStation = this.$route.params.pos === undefined;
console.log("neu: "+this.isNewStation);
console.log("pos: "+this.$route.params.pos);
this.concatLatlang(); this.concatLatlang();
}, },
computed: { computed: {
// concatLatlang() { ...mapGetters({
// return this.station.lattitude+", "+this.station.longitude tempStation: 'cacheCollector/GET_TEMPSTATION'
// } }),
}, },
methods: { methods: {
separateLatlang() { separateLatlang() {
@ -79,11 +86,22 @@
concatLatlang() { concatLatlang() {
this.latlang = this.station.lattitude+", "+this.station.longitude; this.latlang = this.station.lattitude+", "+this.station.longitude;
}, },
addStation() { saveStation() {
//this.$parent.swapComponent(null);
// this.$emit('q-tb');
console.log("saveStation(): ");
if (isNewStation) {
this.$store.commit('cacheCollector/ADD_STATION', this.station);
} else {
this.$store.commit('cacheCollector/EDIT_STATION', this.$route.params.pos, this.station);
this.$store.commit('cacheCollector/SET_TEMPSTATION', null);
}
this.$router.push({ path: `/cache` });
console.log("station saved..");
}, },
dismiss() { dismiss() {
this.$emit('q-tb');
this.$router.push({ path: `/cache` });
} }
} }
} }

View File

@ -16,7 +16,12 @@ const routes = [
children: [{ path: "", component: () => import("pages/Cache.vue") }] children: [{ path: "", component: () => import("pages/Cache.vue") }]
}, },
{ {
path: "/station/", path: "/cache/:id",
component: () => import("layouts/MyLayout.vue"),
children: [{ path: "", component: () => import("pages/Cache.vue") }]
},
{
path: "/station?local=:pos",
component: () => import("layouts/MyLayout.vue"), component: () => import("layouts/MyLayout.vue"),
children: [{ path: "", component: () => import("pages/StationEdit.vue") }] children: [{ path: "", component: () => import("pages/StationEdit.vue") }]
}, },
@ -25,6 +30,17 @@ const routes = [
component: () => import("layouts/MyLayout.vue"), component: () => import("layouts/MyLayout.vue"),
children: [{ path: "", component: () => import("pages/StationView.vue") }] children: [{ path: "", component: () => import("pages/StationView.vue") }]
}, },
{
path: "/station/",
component: () => import("layouts/MyLayout.vue"),
// props: true,
children: [{
path: "",
component: () => import("pages/StationEdit.vue"),
// props: true
//props: ['stationObject']
}]
},
{ {
path: "/login/", path: "/login/",
component: () => import("layouts/MyLayout.vue"), component: () => import("layouts/MyLayout.vue"),

View File

@ -1,4 +1,3 @@
import axios from 'axios'
export const SET_AUTHENTICATED = (state) => { export const SET_AUTHENTICATED = (state) => {
console.log("SET_AUTHENTICATED()"); console.log("SET_AUTHENTICATED()");
console.log(JSON.parse(localStorage.getItem('userToken'))); console.log(JSON.parse(localStorage.getItem('userToken')));

View File

@ -7,6 +7,6 @@ export default {
email: "test@user.com", email: "test@user.com",
rankingPointsSum: 345, rankingPointsSum: 345,
isAuthenticated: false, isAuthenticated: false,
isAdmin: false, isAdmin: true,
}, },
} }

View File

@ -1,4 +1,8 @@
/* export const GET_CACHE = (state) => {
export function someGetter (state) { console.log("GET_CACHE: retrieve cache from store. ");
} return state.newCache;
*/ };
export const GET_TEMPSTATION = (state) => {
console.log("GET_TEMPSTATION: retrieve cache from store. ");
return state.tempStation;
};

View File

@ -1,4 +1,53 @@
/* export const SET_CACHE = (state, cache) => {
export function someMutation (state) { console.log("SET_CACHE: save cache to store. ")
} state.newCache = cache;
*/ };
export const SET_TEMPSTATION = (state, station) => {
console.log("SET_TEMPSTATION: add new station to cache: "+station);
state.tempStation = station;
};
export const ADD_STATION = (state, station) => {
console.log("ADD_STATION: add new station to cache: "+station);
state.newCache.stationen.push(station);
};
export const EDIT_STATION = (state, index, station) => {
console.log("ADD_STATION: add new station to cache: "+station);
state.newCache.stationen[index] = station;
};
export const REMOVE_STATION = (state, index) => {
console.log("ADD_STATION: add new station to cache: "+station);
state.newCache.stationen.splice(index,1);
};
export const RESET_NEW_CACHE = (state) => {
state.newCache = {
id: null,
name: "",
description: "",
rankingPoints: 0,
stationen: []
};
console.log("resetted new Cache");
};
export const LOAD_REMOTE_CACHE = (state, id) => {
console.log("LOAD_REMOTE_CACHE: get caches from remote");
this.$axios.get('http://localhost:8080/api/allCaches')
.then((response) => {
const allCaches = JSON.parse(response.data);
console.log("Caches: " + allCaches.length);
if (response.data === undefined || allCaches.length === 0) {
console.log("aborted processing data.");
return;
}
let cacheToSet = null;
for (let cache in allCaches) {
console.log("Cachedata: ");
console.log(cache.id);
console.log(cache.name);
if (cache.id === id) {
cacheToSet = cache;
console.log("found matching ID: setted cache to store.");
break;
}
}
});
};

View File

@ -1,3 +1,38 @@
export default { export default {
// newCache: {
name: "Blumencache",
description: "Dieser Cache umfasst 4 Stationen mit Rätseln rund um das Thema Blumen",
rankingPoints: 100,
stationen: [
{
description: "Ein kleines winterliches Schlaginstrument. Welche Blume ist damit gemeint?",
longitude: 9.206628,
lattitude: 49.147734,
code: 213812,
solution: "Schneeglöckchen"
},
{
description: "Ein blühendes Federvieh. Welche Blume ist damit gemeint?",
longitude: 9.206806,
lattitude: 49.147318,
code: 237823,
solution: "Gänseblümchen"
},
{
description: "Eine wertvolle Farbe. Welche Blume ist damit gemeint?",
longitude: 9.207844,
lattitude: 49.148032,
code: 899423,
solution: "Edelweiß"
},
{
description: "Ein Zerkleinerungsgerät in der Brüllöffnung eines Raubtieres. Welche Blume ist damit gemeint?",
longitude: 9.207649,
lattitude: 49.150142,
code: 347923,
solution: "Löwenzahn"
}
]
},
tempStation: {},
} }

View File

@ -3,11 +3,19 @@ package hhn.labsw.bugageocaching;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication @SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class Application { public class Application{
public static void main(String[] args) { /**@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}**/
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args); SpringApplication.run(Application.class, args);
} }
} }

View File

@ -5,14 +5,24 @@ import com.google.gson.GsonBuilder;
import hhn.labsw.bugageocaching.entities.*; import hhn.labsw.bugageocaching.entities.*;
import hhn.labsw.bugageocaching.exceptions.IllegalParameterException; import hhn.labsw.bugageocaching.exceptions.IllegalParameterException;
import hhn.labsw.bugageocaching.repositories.*; import hhn.labsw.bugageocaching.repositories.*;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
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.crypto.bcrypt.BCrypt; import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.security.SecureRandom;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
@RestController @RestController
public class Controller { public class Controller {
@ -39,6 +49,13 @@ public class Controller {
UserRepository userRepository; UserRepository userRepository;
private AtomicLong counter = new AtomicLong(); private AtomicLong counter = new AtomicLong();
byte[] key = new byte[64];
@PostConstruct
public void init() {
new SecureRandom().nextBytes(key);
System.out.println(Arrays.toString(key));
}
@CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose
@RequestMapping("/api/allCaches") @RequestMapping("/api/allCaches")
@ -60,14 +77,37 @@ public class Controller {
return ResponseEntity.status(404).body("User was not found"); return ResponseEntity.status(404).body("User was not found");
} }
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
if (BCrypt.checkpw(user.getPassword(), userRepository.findByUsername(user.getUsername()).getPassword())) { if (BCrypt.checkpw(user.getPassword(), userRepository.findByUsername(user.getUsername()).getPassword())) {
String token = Jwts.builder()
.setSubject(user.getUsername())
.claim("admin", userRepository.findByUsername(user.getUsername()).getRoles().stream().anyMatch(x -> x.getId() == 0)) //True if user is admin
.setExpiration(new Date(new Date().getTime() + (1000 * 60 * 60 * 24))) //One day expiration
.signWith(signatureAlgorithm, key)
.compact();
System.out.println(token);
Claims claims = Jwts.parser() //Parse JWT
.setSigningKey(key)
.parseClaimsJws(token).getBody();
System.out.println("ID: " + claims.getId());
System.out.println("Subject: " + claims.getSubject());
System.out.println("Issuer: " + claims.getIssuer());
System.out.println("Admin: " + claims.get("admin"));
System.out.println("Expiration: " + claims.getExpiration());
return ResponseEntity.status(200).body(token);
}
/*if (BCrypt.checkpw(user.getPassword(), userRepository.findByUsername(user.getUsername()).getPassword())) {
String token = user.getUsername() + BCrypt.hashpw(String.valueOf(System.currentTimeMillis() + counter.incrementAndGet()), BCrypt.gensalt()); String token = user.getUsername() + BCrypt.hashpw(String.valueOf(System.currentTimeMillis() + counter.incrementAndGet()), BCrypt.gensalt());
String hashedToken = BCrypt.hashpw(token, BCrypt.gensalt()); String hashedToken = BCrypt.hashpw(token, BCrypt.gensalt());
userRepository.findByUsername(user.getUsername()).setToken(hashedToken); userRepository.findByUsername(user.getUsername()).setToken(hashedToken);
userRepository.save(userRepository.findByUsername(user.getUsername())); userRepository.save(userRepository.findByUsername(user.getUsername()));
//return ResponseEntity.ok(new Gson().toJson(token)); //return ResponseEntity.ok(new Gson().toJson(token));
return ResponseEntity.status(200).body(token); return ResponseEntity.status(200).body(token);
} }*/
return ResponseEntity.status(400).body("Es ist ein Fehler aufgetreten"); return ResponseEntity.status(400).body("Es ist ein Fehler aufgetreten");
} }
@ -81,16 +121,22 @@ public class Controller {
Bearbeitet bearbeitet = new Bearbeitet(); Bearbeitet bearbeitet = new Bearbeitet();
User user = userRepository.findByUsername(token.substring(0, token.indexOf("$"))); try {
if (user == null) { Claims claims = Jwts.parser() //Parse JWT
return ResponseEntity.status(404).body("User was not found"); .setSigningKey(key)
} .parseClaimsJws(token).getBody();
bearbeitet.setUser(user);
Optional<Cache> cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID));
if (cacheOptional.isPresent()) { User user = userRepository.findByUsername(claims.getSubject());
Cache cache = cacheOptional.get(); if (user == null) {
bearbeitet.setCache(cache); return ResponseEntity.status(404).body("User was not found");
}
bearbeitet.setUser(user);
Optional<Cache> cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID));
if (cacheOptional.isPresent()) {
Cache cache = cacheOptional.get();
bearbeitet.setCache(cache);
Station startStation = cache.getStationen().get(0); Station startStation = cache.getStationen().get(0);
bearbeitet.setAktuelleStation(startStation); bearbeitet.setAktuelleStation(startStation);
@ -107,9 +153,14 @@ public class Controller {
return ResponseEntity.status(404).body("There is no cacheAccesDefinition with the ID " + 0); return ResponseEntity.status(404).body("There is no cacheAccesDefinition with the ID " + 0);
} }
bearbeitetRepository.save(bearbeitet); bearbeitetRepository.save(bearbeitet);
return ResponseEntity.status(200).body(new Gson().toJson(bearbeitet)); return ResponseEntity.status(200).body(new Gson().toJson(bearbeitet));
} catch (ExpiredJwtException e) {
return ResponseEntity.status(400).body("JWT Token expired");
} catch (Exception e){
return ResponseEntity.status(400).body("JWT Token invalid");
}
} else { // kein angemeldeter User startet den cache(es wird nur der cache als parameter übergeben) } else { // kein angemeldeter User startet den cache(es wird nur der cache als parameter übergeben)
Optional<Cache> cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID)); Optional<Cache> cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID));
@ -122,19 +173,20 @@ public class Controller {
} }
} }
//Eigentlich brauchen wir mit JWT keine Logout Methode mehr.
@CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose
@RequestMapping("/api/logout") @RequestMapping("/api/logout")
@ResponseBody @ResponseBody
public ResponseEntity logout(@RequestParam String token) { public ResponseEntity logout(@RequestParam String token) {
// System.out.println("logout"); // System.out.println("logout");
User user = userRepository.findByUsername(token.substring(0, token.indexOf("$"))); /*User user = userRepository.findByUsername(token.substring(0, token.indexOf("$")));
// System.out.println(token); // System.out.println(token);
// System.out.println(user.getToken()); // System.out.println(user.getToken());
if (user == null || user.getToken().isEmpty()) { if (user == null || user.getToken().isEmpty()) {
return ResponseEntity.status(404).body("User was not found"); return ResponseEntity.status(404).body("User was not found");
} }
user.setToken(null); user.setToken(null);
userRepository.save(user); userRepository.save(user);*/
return ResponseEntity.status(200).body("Token was deleted"); return ResponseEntity.status(200).body("Token was deleted");
} }
@ -226,7 +278,20 @@ public class Controller {
@RequestMapping("/api/checkAdmin") @RequestMapping("/api/checkAdmin")
@ResponseBody @ResponseBody
public ResponseEntity checkAdmin(@RequestParam String token) { public ResponseEntity checkAdmin(@RequestParam String token) {
User user = userRepository.findByUsername(token.substring(0, token.indexOf("$")));
try {
Claims claims = Jwts.parser() //Parse JWT
.setSigningKey(key)
.parseClaimsJws(token).getBody();
return ResponseEntity.status(200).body(claims.get("admin"));
}catch (ExpiredJwtException e) {
return ResponseEntity.status(400).body("JWT Token expired");
} catch (Exception e){
return ResponseEntity.status(400).body("JWT Token invalid");
}
/*User user = userRepository.findByUsername(token.substring(0, token.indexOf("$")));
if (user == null) { if (user == null) {
return ResponseEntity.status(404).body("User was not found"); return ResponseEntity.status(404).body("User was not found");
} }
@ -235,7 +300,7 @@ public class Controller {
return ResponseEntity.status(200).body("User is Admin"); return ResponseEntity.status(200).body("User is Admin");
} }
} }
return ResponseEntity.status(401).body("User is no Admin"); return ResponseEntity.status(401).body("User is no Admin");*/
} }
//Bis hier //Bis hier
@ -273,7 +338,14 @@ public class Controller {
@ResponseBody @ResponseBody
public ResponseEntity getMyCaches(@RequestParam String token) { public ResponseEntity getMyCaches(@RequestParam String token) {
try { try {
User user = userRepository.findByUsername(token.substring(0, token.indexOf("$")));
Claims claims = Jwts.parser() //Parse JWT
.setSigningKey(key)
.parseClaimsJws(token).getBody();
User user = userRepository.findByUsername(claims.getSubject());
if (user != null) { if (user != null) {
ArrayList<Bearbeitet> bearbeitetList = new ArrayList<>(); ArrayList<Bearbeitet> bearbeitetList = new ArrayList<>();
@ -286,8 +358,10 @@ public class Controller {
} else { } else {
return ResponseEntity.status(404).body("User was not found in the database"); return ResponseEntity.status(404).body("User was not found in the database");
} }
} catch (StringIndexOutOfBoundsException e) { } catch (ExpiredJwtException e) {
return ResponseEntity.status(400).body("Invalid token"); return ResponseEntity.status(400).body("JWT Token expired");
} catch (Exception e){
return ResponseEntity.status(400).body("JWT Token invalid");
} }
} }
@ -314,14 +388,21 @@ public class Controller {
@ResponseBody @ResponseBody
public ResponseEntity getUser(@RequestParam String token) { public ResponseEntity getUser(@RequestParam String token) {
try { try {
User user = userRepository.findByUsername(token.substring(0, token.indexOf("$"))); Claims claims = Jwts.parser() //Parse JWT
.setSigningKey(key)
.parseClaimsJws(token).getBody();
User user = userRepository.findByUsername(claims.getSubject());
if (user != null) { if (user != null) {
return ResponseEntity.status(200).body(new Gson().toJson(user)); return ResponseEntity.status(200).body(new Gson().toJson(user));
} else { } else {
return ResponseEntity.status(404).body("User was not found in the database"); return ResponseEntity.status(404).body("User was not found in the database");
} }
} catch (StringIndexOutOfBoundsException e) { } catch (ExpiredJwtException e) {
return ResponseEntity.status(400).body("Invalid token"); return ResponseEntity.status(400).body("JWT Token expired");
} catch (Exception e){
return ResponseEntity.status(400).body("JWT Token invalid");
} }
} }
} }

View File

@ -31,4 +31,9 @@ public class Role {
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
@Override
public String toString() {
return name;
}
} }

View File

@ -1,8 +1,12 @@
package hhn.labsw.bugageocaching.entities; package hhn.labsw.bugageocaching.entities;
import javax.persistence.*; import javax.persistence.*;
import java.util.Set;
import java.util.List; import java.util.List;
@Entity @Entity
@Table @Table
public class User { public class User {
@ -18,14 +22,17 @@ public class User {
private String email; private String email;
private String password; private String password;
@ManyToMany @ManyToMany
private List<Role> roles; private List<Role> roles;
private String token;
@ManyToOne @ManyToOne
private Team team; private Team team;
@Transient
private String passwordConfirm;
public int getId() { public int getId() {
return id; return id;
} }
@ -98,11 +105,4 @@ public class User {
this.roles = roles; this.roles = roles;
} }
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
} }

View File

@ -1,7 +1,8 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.Bearbeitet; import hhn.labsw.bugageocaching.entities.Bearbeitet;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface BearbeitetRepository extends CrudRepository<Bearbeitet, Integer> { public interface BearbeitetRepository extends JpaRepository<Bearbeitet, Integer> {
} }

View File

@ -1,7 +1,8 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.CacheAccesDefinition; import hhn.labsw.bugageocaching.entities.CacheAccesDefinition;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface CacheAccesDefinitionRepository extends CrudRepository<CacheAccesDefinition, Integer> { public interface CacheAccesDefinitionRepository extends JpaRepository<CacheAccesDefinition, Integer> {
} }

View File

@ -1,7 +1,8 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.Cache; import hhn.labsw.bugageocaching.entities.Cache;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface CacheRepository extends CrudRepository<Cache, Integer> { public interface CacheRepository extends JpaRepository<Cache, Integer> {
} }

View File

@ -1,7 +1,8 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.Reward; import hhn.labsw.bugageocaching.entities.Reward;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface RewardRepository extends CrudRepository<Reward, Integer> { public interface RewardRepository extends JpaRepository<Reward, Integer> {
} }

View File

@ -0,0 +1,7 @@
package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.Role;
import org.springframework.data.jpa.repository.JpaRepository;
public interface RoleRepository extends JpaRepository<Role, Integer> {
}

View File

@ -1,7 +1,8 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.Station; import hhn.labsw.bugageocaching.entities.Station;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface StationRepository extends CrudRepository<Station, Integer> { public interface StationRepository extends JpaRepository<Station, Integer> {
} }

View File

@ -1,7 +1,8 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.Team; import hhn.labsw.bugageocaching.entities.Team;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface TeamRepository extends CrudRepository<Team, Integer> { public interface TeamRepository extends JpaRepository<Team, Integer> {
} }

View File

@ -1,6 +1,10 @@
package hhn.labsw.bugageocaching.repositories; package hhn.labsw.bugageocaching.repositories;
import hhn.labsw.bugageocaching.entities.User; import hhn.labsw.bugageocaching.entities.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
@ -12,4 +16,5 @@ public interface UserRepository extends CrudRepository<User, Integer> {
@Query(value = "SELECT u.id, u.username, u.ranking_points_sum from user u order by ranking_points_sum DESC", nativeQuery = true) @Query(value = "SELECT u.id, u.username, u.ranking_points_sum from user u order by ranking_points_sum DESC", nativeQuery = true)
List<Object[]> getRankingList(); List<Object[]> getRankingList();
} }