Add search

This commit is contained in:
Torjus Håkestad 2021-04-14 17:27:03 +02:00
parent 946bdd2a6a
commit f4afd8df62
6 changed files with 130 additions and 15 deletions

View File

@ -2,7 +2,7 @@ package apiary
import "fmt" import "fmt"
var Version = "v0.1.1" var Version = "v0.1.2"
var Build string var Build string
func FullVersion() string { func FullVersion() string {

View File

@ -18,6 +18,7 @@
<b-nav-item :to="'/'">Home</b-nav-item> <b-nav-item :to="'/'">Home</b-nav-item>
<b-nav-item :to="'/stats'">Stats</b-nav-item> <b-nav-item :to="'/stats'">Stats</b-nav-item>
<b-nav-item :to="'/attempts'">Attempts</b-nav-item> <b-nav-item :to="'/attempts'">Attempts</b-nav-item>
<b-nav-item :to="'/search'">Search</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-collapse> </b-collapse>
</b-navbar> </b-navbar>

View File

@ -8,7 +8,7 @@
hover hover
:items="attempts" :items="attempts"
:fields="fields" :fields="fields"
></b-table> />
</p> </p>
</div> </div>
</template> </template>

View File

@ -0,0 +1,81 @@
<template>
<div class="search-result-container">
<h1>Search</h1>
<b-form @submit="onSubmit">
<b-form-input v-model="searchString" placeholder="" />
</b-form>
<b-table
class="search-results-table"
responsive="md"
striped
hover
:items="attempts"
:fields="fields"
/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { LoginAttempt } from '@/apiary/apiary';
import { BvTableFieldArray, BvTableFormatterCallback } from 'bootstrap-vue';
import Axios from 'axios';
@Component
export default class SearchResult extends Vue {
attempts: LoginAttempt[];
searchString: string;
constructor() {
super();
this.attempts = [];
this.searchString = '';
}
fields: BvTableFieldArray = [
{
key: 'date',
sortable: true,
formatter: (value: string): string => {
const d = new Date(value);
// This seems stupid...
return d.toTimeString().split(' ')[0];
},
sortByFormatted: false,
},
{
key: 'username',
},
{
key: 'password',
},
{
key: 'remoteIP',
sortable: true,
},
{
key: 'country',
},
];
onSubmit(event: Event) {
event.preventDefault();
console.log(this.searchString);
const resp = Axios.get<LoginAttempt[]>(
`/api/query?query=${this.searchString}`,
);
resp.then((r) => {
this.attempts = r.data;
});
}
}
</script>
<style lang="scss" scoped>
.search-results-table {
margin-top: 50px;
}
</style>

View File

@ -4,6 +4,7 @@ import VueRouter, { RouteConfig } from 'vue-router';
import AttemptList from '@/components/AttemptList.vue'; import AttemptList from '@/components/AttemptList.vue';
import Home from '@/components/Home.vue'; import Home from '@/components/Home.vue';
import Stats from '@/components/Stats.vue'; import Stats from '@/components/Stats.vue';
import SearchResult from '@/components/SearchResult.vue';
import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css'; import 'bootstrap-vue/dist/bootstrap-vue.css';
import '@fontsource/rubik'; import '@fontsource/rubik';
@ -38,6 +39,11 @@ const routes: Array<RouteConfig> = [
name: 'Stats', name: 'Stats',
component: Stats, component: Stats,
}, },
{
path: '/search',
name: 'Search',
component: SearchResult,
}
]; ];
const router = new VueRouter({ const router = new VueRouter({

View File

@ -216,24 +216,51 @@ func (s *Server) HandlerQuery(w http.ResponseWriter, r *http.Request) {
queryType := r.URL.Query().Get("type") queryType := r.URL.Query().Get("type")
query := r.URL.Query().Get("query") query := r.URL.Query().Get("query")
if query == "" || queryType == "" { if query == "" {
s.WriteAPIError(w, r, http.StatusBadRequest, "Invalid query or query type") s.WriteAPIError(w, r, http.StatusBadRequest, "Invalid query or query type")
return return
} }
aq := store.AttemptQuery{ results := []models.LoginAttempt{}
QueryType: store.AttemptQueryType(queryType), if queryType == "" {
uq := store.AttemptQuery{
QueryType: store.AttemptQueryType(store.AttemptQueryTypePassword),
Query: query, Query: query,
} }
pq := store.AttemptQuery{
results, err := s.store.Query(aq) QueryType: store.AttemptQueryType(store.AttemptQueryTypeUsername),
Query: query,
}
userResults, err := s.store.Query(uq)
if err != nil { if err != nil {
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query") s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
s.ServerLogger.Warnw("Error performing query", "error", err) s.ServerLogger.Warnw("Error performing query", "error", err)
return return
} }
if results == nil { passwordResults, err := s.store.Query(pq)
results = []models.LoginAttempt{} if err != nil {
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
s.ServerLogger.Warnw("Error performing query", "error", err)
return
}
results = append(results, userResults...)
results = append(results, passwordResults...)
} else {
aq := store.AttemptQuery{
QueryType: store.AttemptQueryType(queryType),
Query: query,
}
queryResults, err := s.store.Query(aq)
if err != nil {
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
s.ServerLogger.Warnw("Error performing query", "error", err)
return
}
results = append(results, queryResults...)
} }
encoder := json.NewEncoder(w) encoder := json.NewEncoder(w)