Browse Source

Minor fixes in Backend + Frontend finished

pull/1/head
Slixe 2 years ago
parent
commit
88b7095dc0
14 changed files with 210 additions and 41 deletions
  1. +15
    -5
      dero-benchmark-vue/src/App.vue
  2. +2
    -0
      dero-benchmark-vue/src/main.js
  3. +3
    -1
      dero-benchmark-vue/src/router.js
  4. +4
    -3
      dero-benchmark-vue/src/views/Index.vue
  5. +14
    -4
      dero-benchmark-vue/src/views/Submit.vue
  6. +10
    -9
      dero-benchmark-vue/src/views/auth/Login.vue
  7. +114
    -2
      dero-benchmark-vue/src/views/auth/UBenchmarks.vue
  8. +5
    -0
      src/main/java/fr/slixe/benchmarks/Benchmark.java
  9. +1
    -1
      src/main/java/fr/slixe/benchmarks/Main.java
  10. +4
    -1
      src/main/java/fr/slixe/benchmarks/http/controller/AuthController.groovy
  11. +5
    -1
      src/main/java/fr/slixe/benchmarks/http/controller/MainController.groovy
  12. +12
    -1
      src/main/java/fr/slixe/benchmarks/serialization/UserAdapter.java
  13. +12
    -4
      src/main/java/fr/slixe/benchmarks/service/BenchmarkService.java
  14. +9
    -9
      src/main/resources/config/routes.groovy

+ 15
- 5
dero-benchmark-vue/src/App.vue View File

@@ -17,11 +17,21 @@
export default {
name: 'App',
mounted() {
fetch("/api/auth/validate", { method: "POST" }).then(result => result.json()).then(json => {
if (!json.logged) {
localStorage.setItem("token", null)
}
})
let token = localStorage.getItem("token")

if (token != null) {
let headers = new Headers();
headers.append("Authorization", "Bearer " + token)

fetch(this.$api + "/api/auth/validate", { method: "POST", headers: headers }).then(result => result.json()).then(json => {
if (json.logged) {
localStorage.setItem("token", json.token)
}
else {
localStorage.removeItem("token")
}
})
}
}
}
</script>


+ 2
- 0
dero-benchmark-vue/src/main.js View File

@@ -7,6 +7,8 @@ import 'material-design-icons-iconfont/dist/material-design-icons.css'

Vue.config.productionTip = false

Vue.prototype.$api = "http://localhost:8081"

Vue.use(Vuetify)
new Vue({
render: h => h(App),


+ 3
- 1
dero-benchmark-vue/src/router.js View File

@@ -3,13 +3,15 @@ import Vue from 'vue'
import Index from './views/Index.vue'
import Sumbit from './views/Submit.vue'
import Login from './views/auth/Login.vue'
import UBenchmarks from './views/auth/UBenchmarks.vue'

Vue.use(VueRouter)

const routes = [
{ path: '/', component: Index },
{ path: '/submit', component: Sumbit },
{ path: '/login', component: Login }
{ path: '/login', component: Login },
{ path: '/unconfirmedBenchmarks', component: UBenchmarks }
];

export default new VueRouter({


+ 4
- 3
dero-benchmark-vue/src/views/Index.vue View File

@@ -1,12 +1,12 @@
<template>
<div id="index">
<v-card class="bench" :loading="loading">
<v-card class="bench elevation-5" :loading="loading">
<v-card-title>
<h2>Benchmarks</h2>
<v-spacer></v-spacer>
<v-text-field class="search" v-model="search" append-icon="magnify" label="Search" single-line hide-details></v-text-field>
</v-card-title>
<v-data-table :search="search" multi-sort :headers="headers" :items="benchmarks" :items-per-page="5" class="elevation-5">
<v-data-table :search="search" multi-sort :headers="headers" :items="benchmarks" :items-per-page="5">
<template v-slot:item.timestamp="{ item }">
<span>{{ new Date(item.timestamp).toLocaleDateString() }}</span>
</template>
@@ -54,7 +54,7 @@ export default {
}
},
mounted() {
fetch("/api/benchmarks").then(result => result.json()).then(json => {
fetch(this.$api + "/api/benchmarks").then(result => result.json()).then(json => {
this.benchmarks = json
this.loading = false
})
@@ -67,5 +67,6 @@ export default {
margin: 10%;
margin-top: 5%;
margin-bottom: 2%;
padding: 2%;
}
</style>

+ 14
- 4
dero-benchmark-vue/src/views/Submit.vue View File

@@ -13,6 +13,7 @@
<v-btn @click="submit()" color="blue">Sumbit</v-btn>
</v-form>
</v-card>
<h4>Back to <router-link to="/">Benchmarks</router-link></h4>
</div>
</template>

@@ -29,28 +30,37 @@ export default {
alertType: "error",
alertMessage: "",
alertShow: false,
submitted: false,
}
},
methods: {
submit() {
if (this.valid) {
fetch("/api/submit", {
if (!this.submitted && this.valid) {
this.submitted = true
fetch(this.$api + "/api/submit", {
method: "POST",
body: JSON.stringify({
vendor: this.vendor,
model: this.model,
hashrate: this.hashrate,
miner: this.miner,
user: this.user
minerVersion: this.miner,
owner: this.user
})
}).then(result => result.json()).then(json => {
this.alertType = json.success ? "success" : "error"
this.alertMessage = json.message
this.alertShow = true

if (json.success) {
setTimeout(() => this.$router.push("/"), 5000)
} else {
this.submitted = false
}
}).catch(() => {
this.alertType = "error"
this.alertMessage = "An error has occurred !"
this.alertShow = true
this.submitted = false
})
}
}


+ 10
- 9
dero-benchmark-vue/src/views/auth/Login.vue View File

@@ -23,16 +23,17 @@ export default {
alertShow: false
}
},
mounted() {
let token = localStorage.getItem("token")
if (token != null && token.length == 86)
{
this.$router.push("/unconfirmedBenchmarks")
}
},
methods: {
mounted() {
if (localStorage.getItem("token") != null)
{
this.$router.push("/unconfirmedBenchmarks")
}
},
login() {
if (this.valid) {
fetch("/api/auth/login", {
fetch(this.$api + "/api/auth/login", {
method: "POST",
body: JSON.stringify({
username: this.username,
@@ -41,11 +42,11 @@ export default {
}).then(result => result.json()).then(json => {
let valid = json.token != null
this.alertType = valid ? "success" : "error"
this.alertMessage = valid ? "You are now logged in!" : (json.error + ": " + json.message)
this.alertMessage = valid ? "You are now logged in!" : json.message
this.alertShow = true
if (valid) {
localStorage.setItem("token", json.token)
setTimeout(() => this.$router.push("/unconfirmedBenchmarks"), 1000 * 5)
setTimeout(() => this.$router.push("/unconfirmedBenchmarks"), 5000)
}
}).catch(() => {
this.alertType = "error"


+ 114
- 2
dero-benchmark-vue/src/views/auth/UBenchmarks.vue View File

@@ -1,12 +1,124 @@
<template>
<div id="ubenchmarks">
<v-card class="bench elevation-5" :loading="loading">
<v-alert v-for="(alert, i) in this.alerts" :key="i" :type="alert.type">{{ alert.message }}</v-alert>
<v-card-title>
<h2>Unconfirmed Benchmarks</h2>
<v-spacer></v-spacer>
<v-text-field class="search" v-model="search" append-icon="magnify" label="Search" single-line hide-details></v-text-field>
</v-card-title>
<v-data-table v-model="selected" show-select :search="search" multi-sort :headers="headers" :items="benchmarks" :items-per-page="5">
<template v-slot:item.timestamp="{ item }">
<span>{{ new Date(item.timestamp).toLocaleDateString() }}</span>
</template>
</v-data-table>
<div class="buttons">
<v-btn @click="update(false)" color="red">Delete</v-btn>
<v-btn @click="update(true)" color="green">Confirm</v-btn>
</div>
</v-card>
<h4>Back to confirmed <router-link to="/">Benchmarks</router-link></h4>
</div>
</template>

<script>
export default {
data() {
return {
loading: true,
search: "",
selected: [],
headers: [
{
text: "Vendor",
align: "start",
value: "vendor"
},
{
text: "Model",
value: "model"
},
{
text: "Hashrate (h/s)",
value: "hashrate"
},
{
text: "Miner",
value: "minerVersion"
},
{
text: "Submitted On",
value: "timestamp",
class: "Date"
},
{
text: "User",
value: "owner"
}
],
benchmarks: [],
alerts: []
}
},
mounted() {
let token = localStorage.getItem("token")
if (token == null || token.length != 86) //TODO must wait App.mounted()
{
this.$router.push("/login")
return
}

let headers = new Headers();
headers.append("Authorization", "Bearer " + token)

fetch(this.$api + "/api/unconfirmedBenchmarks", { headers: headers }).then(result => result.json()).then(json => {
this.benchmarks = json
this.loading = false
})
},
methods: {
update(confirm) {
let headers = new Headers();
let token = localStorage.getItem("token")
headers.append("Authorization", "Bearer " + token)

let localSelected = this.selected
for (let bench of localSelected)
{
fetch(this.$api + "/api/" + (confirm ? "confirm" : "delete"), {
method: "POST",
headers: headers,
body: JSON.stringify({
benchID: bench.id
})
}).then(result => result.json()).then(json => {
this.alerts.push({
type: json.success ? "success" : "error",
message: json.message
})
setTimeout(() => this.alerts.shift(), 5000)

if (json.success) {
let index = this.benchmarks.findIndex(x => x.id == bench.id)
this.benchmarks.splice(index, 1)
this.selected.shift()
}
})
}
}
}
}
</script>

<style scoped>

.bench {
margin: 10%;
margin-top: 5%;
margin-bottom: 2%;
padding: 2%;
}
.buttons {
display: flex;
justify-content: space-evenly;
}
</style>

+ 5
- 0
src/main/java/fr/slixe/benchmarks/Benchmark.java View File

@@ -21,6 +21,11 @@ public class Benchmark {
this.timestamp = timestamp;
}

public void setId(int id)
{
this.id = id;
}
public int getId()
{
return id;


+ 1
- 1
src/main/java/fr/slixe/benchmarks/Main.java View File

@@ -22,4 +22,4 @@ public class Main
{
return paladin;
}
}
}

+ 4
- 1
src/main/java/fr/slixe/benchmarks/http/controller/AuthController.groovy View File

@@ -7,6 +7,7 @@ import com.google.inject.Inject

import fr.litarvan.paladin.Session
import fr.litarvan.paladin.http.Controller
import fr.litarvan.paladin.http.routing.JsonBody
import fr.litarvan.paladin.http.routing.RequestParams
import fr.slixe.benchmarks.User
import fr.slixe.benchmarks.http.InvalidParameterException
@@ -19,6 +20,7 @@ public class AuthController extends Controller {
@Inject
private AuthService authService

@JsonBody
@RequestParams(required = ["username", "password"])
def login(String username, String password, Session session)
{
@@ -32,7 +34,7 @@ public class AuthController extends Controller {
throw new InvalidParameterException("Username or password is incorrect")
}

log.info(String.format("User %s is now logged in from %s.", user.getUsername()))
log.info(String.format("User %s is now logged in.", user.getUsername()))

session[User] = user

@@ -44,6 +46,7 @@ public class AuthController extends Controller {
def validate(Session session)
{
[
token: session.token,
logged: session[User] != null
]
}


+ 5
- 1
src/main/java/fr/slixe/benchmarks/http/controller/MainController.groovy View File

@@ -7,6 +7,7 @@ import com.google.gson.Gson;
import com.google.inject.Inject;

import fr.litarvan.paladin.http.Controller;
import fr.litarvan.paladin.http.routing.JsonBody
import fr.litarvan.paladin.http.routing.RequestParams;
import fr.slixe.benchmarks.Benchmark;
import fr.slixe.benchmarks.Benchmark.Vendor
@@ -47,12 +48,13 @@ public class MainController extends Controller {
* @param String minerVersion (XMRig 5.9.0)
* @param String owner (Slixe)
*/
@JsonBody
@RequestParams(required = ["vendor", "model", "hashrate", "minerVersion", "owner"])
def submit(Vendor vendor, String model, long hashrate, String minerVersion, String owner)
{
log.debug("A new benchmark has been submitted!")
Benchmark benchmark = new Benchmark(benchmarkService.lastBenchId(), vendor, model, hashrate, minerVersion, owner)
Benchmark benchmark = new Benchmark(benchmarkService.lastUnconfirmedBenchId(), vendor, model, hashrate, minerVersion, owner, System.currentTimeMillis())
benchmarkService.addUnconfirmedBenchmarks(benchmark)

[
@@ -66,6 +68,7 @@ public class MainController extends Controller {
* accessible from: api/confirm
* @param int benchID
*/
@JsonBody
@RequestParams(required = ["benchID"])
def confirm(int benchID)
{
@@ -84,6 +87,7 @@ public class MainController extends Controller {
* accessible from: api/delete
* @param int benchID
*/
@JsonBody
@RequestParams(required = ["benchID"])
def delete(int benchID)
{


+ 12
- 1
src/main/java/fr/slixe/benchmarks/serialization/UserAdapter.java View File

@@ -11,6 +11,7 @@ import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import fr.slixe.benchmarks.User;
import fr.slixe.benchmarks.service.AuthService;

public class UserAdapter implements JsonSerializer<User>, JsonDeserializer<User> {

@@ -20,9 +21,19 @@ public class UserAdapter implements JsonSerializer<User>, JsonDeserializer<User>
JsonObject jsonObject = json.getAsJsonObject();

String username = jsonObject.get("username").getAsString();
String hashedPassword = jsonObject.get("hashedPassword").getAsString();
String salt = jsonObject.get("salt").getAsString();

String hashedPassword = "no password";
if (jsonObject.has("password")) {
String password = jsonObject.get("password").getAsString();
hashedPassword = AuthService.hash(password, salt);
}
else if (jsonObject.has("hashedPassword")) {
hashedPassword = jsonObject.get("hashedPassword").getAsString();
}
return new User(username, hashedPassword, salt);
}



+ 12
- 4
src/main/java/fr/slixe/benchmarks/service/BenchmarkService.java View File

@@ -91,6 +91,7 @@ public class BenchmarkService {
if (opt.isPresent()) {
Benchmark benchmark = opt.get();
this.unconfirmedBenchmarks.remove(benchmark);
benchmark.setId(lastBenchId());
this.confirmedBenchmarks.add(benchmark);
saveBenchmarks();
}
@@ -113,15 +114,22 @@ public class BenchmarkService {
return result;
}

public int lastUnconfirmedBenchId()
{
if (this.unconfirmedBenchmarks.size() == 0)
return 0;
int b = this.unconfirmedBenchmarks.get(this.unconfirmedBenchmarks.size() - 1).getId() + 1;

return b;
}

public int lastBenchId()
{
if (this.confirmedBenchmarks.size() == 0 && this.unconfirmedBenchmarks.size() == 0)
if (this.confirmedBenchmarks.size() == 0)
return 0;

int a = this.confirmedBenchmarks.get(this.confirmedBenchmarks.size() - 1).getId() + 1;
int b = this.unconfirmedBenchmarks.get(this.unconfirmedBenchmarks.size() - 1).getId() + 1;

return a < b ? b : a;
return a;
}
public List<Benchmark> getBenchmarks()


+ 9
- 9
src/main/resources/config/routes.groovy View File

@@ -2,22 +2,22 @@ package config;
group '/api', {
get '/benchmarks', 'main:benchmarks'
post '/submit', 'main:submit'
group '', {
get '/unconfirmedBenchmarks'
post '/submit'
post '/confirm'
post '/delete'
}, [
action: 'main',
middleware: 'auth'
]
}
group '/auth', {
post '/validate'
post '/login'
post '/logout'
}, [
action: 'auth'
]
}
group '/api/auth', { //not recognized in group /api
post '/validate'
post '/login'
post '/logout'
}, [
action: 'auth'
]

Loading…
Cancel
Save