hunterlong 2020-03-21 17:35:33 -07:00
parent af989a2399
commit 4327569bac
16 changed files with 73 additions and 64 deletions

View File

@ -200,8 +200,8 @@ class Api {
return localStorage.removeItem(tokenKey) return localStorage.removeItem(tokenKey)
} }
saveToken(username, token) { saveToken(username, token, admin) {
const user = {username: username, token: token} const user = {username: username, token: token, admin: admin}
localStorage.setItem(tokenKey, JSON.stringify(user)); localStorage.setItem(tokenKey, JSON.stringify(user));
return user return user
} }

View File

@ -21,7 +21,7 @@
</td> </td>
<td class="d-none d-md-table-cell">{{niceDate(message.start_on)}}</td> <td class="d-none d-md-table-cell">{{niceDate(message.start_on)}}</td>
<td class="text-right"> <td class="text-right">
<div class="btn-group"> <div v-if="$store.state.admin" class="btn-group">
<a @click.prevent="editMessage(message, edit)" href="#" class="btn btn-outline-secondary"><i class="fas fa-exclamation-triangle"></i> Edit</a> <a @click.prevent="editMessage(message, edit)" href="#" class="btn btn-outline-secondary"><i class="fas fa-exclamation-triangle"></i> Edit</a>
<a @click.prevent="deleteMessage(message)" href="#" class="btn btn-danger"><font-awesome-icon icon="times" /></a> <a @click.prevent="deleteMessage(message)" href="#" class="btn btn-danger"><font-awesome-icon icon="times" /></a>
</div> </div>
@ -33,7 +33,7 @@
</div> </div>
</div> </div>
<FormMessage :edit="editChange" :in_message="message"/> <FormMessage v-if="$store.state.admin" :edit="editChange" :in_message="message"/>
</div> </div>
</template> </template>

View File

@ -2,7 +2,7 @@
<div class="col-12"> <div class="col-12">
<div class="card contain-card text-black-50 bg-white mb-4"> <div class="card contain-card text-black-50 bg-white mb-4">
<div class="card-header">Services <div class="card-header">Services
<router-link to="/dashboard/create_service" class="btn btn-sm btn-outline-success float-right"> <router-link v-if="$store.state.admin" to="/dashboard/create_service" class="btn btn-sm btn-outline-success float-right">
<font-awesome-icon icon="plus"/> Create <font-awesome-icon icon="plus"/> Create
</router-link></div> </router-link></div>
<div class="card-body"> <div class="card-body">
@ -34,7 +34,7 @@
<span v-if="!group.public" class="badge badge-secondary">PRIVATE</span> <span v-if="!group.public" class="badge badge-secondary">PRIVATE</span>
</td> </td>
<td class="text-right"> <td class="text-right">
<div class="btn-group"> <div v-if="$store.state.admin" class="btn-group">
<a @click.prevent="editGroup(group, edit)" href="#" class="btn btn-outline-secondary"><font-awesome-icon icon="chart-area" /> Edit</a> <a @click.prevent="editGroup(group, edit)" href="#" class="btn btn-outline-secondary"><font-awesome-icon icon="chart-area" /> Edit</a>
<a @click.prevent="deleteGroup(group)" href="#" class="btn btn-danger"> <a @click.prevent="deleteGroup(group)" href="#" class="btn btn-danger">
<font-awesome-icon icon="times" /> <font-awesome-icon icon="times" />
@ -50,7 +50,7 @@
</div> </div>
<FormGroup :edit="editChange" :in_group="group"/> <FormGroup v-if="$store.state.admin" :edit="editChange" :in_group="group"/>
</div> </div>

View File

@ -31,7 +31,7 @@
</div> </div>
</div> </div>
<FormUser :edit="editChange" :in_user="user"/> <FormUser v-if="$store.state.admin" :edit="editChange" :in_user="user"/>
</div> </div>
</template> </template>

View File

@ -12,11 +12,11 @@
<draggable tag="tbody" v-model="servicesList" handle=".drag_icon"> <draggable tag="tbody" v-model="servicesList" handle=".drag_icon">
<tr v-for="(service, index) in $store.getters.servicesInOrder" :key="service.id"> <tr v-for="(service, index) in $store.getters.servicesInOrder" :key="service.id">
<td> <td>
<span class="drag_icon d-none d-md-inline"> <span v-if="$store.state.admin" class="drag_icon d-none d-md-inline">
<font-awesome-icon icon="bars" class="mr-3"/> <font-awesome-icon icon="bars" class="mr-3"/>
</span> {{service.name}} </span> {{service.name}}
</td> </td>
<td class="d-none d-md-table-cell"> <td v-if="$store.state.admin" class="d-none d-md-table-cell">
<ToggleSwitch v-if="service.online" :service="service"/> <ToggleSwitch v-if="service.online" :service="service"/>
</td> </td>
<td class="d-none d-md-table-cell"> <td class="d-none d-md-table-cell">
@ -25,17 +25,19 @@
</span> </span>
</td> </td>
<td class="d-none d-md-table-cell"> <td class="d-none d-md-table-cell">
<div v-if="service.group_id !== 0"><span class="badge badge-secondary">{{serviceGroup(service)}}</span></div> <div v-if="service.group_id !== 0">
<span class="badge badge-secondary">{{serviceGroup(service)}}</span>
</div>
</td> </td>
<td class="text-right"> <td class="text-right">
<div class="btn-group"> <div class="btn-group">
<router-link :to="{path: `/dashboard/edit_service/${service.id}`, params: {service: service} }" class="btn btn-outline-secondary"> <router-link v-if="$store.state.admin" :to="{path: `/dashboard/edit_service/${service.id}`, params: {service: service} }" class="btn btn-outline-secondary">
<i class="fas fa-chart-area"></i> Edit <i class="fas fa-chart-area"></i> Edit
</router-link> </router-link>
<router-link :to="{path: serviceLink(service), params: {service: service} }" class="btn btn-outline-secondary"> <router-link :to="{path: serviceLink(service), params: {service: service} }" class="btn btn-outline-secondary">
<i class="fas fa-chart-area"></i> View <i class="fas fa-chart-area"></i> View
</router-link> </router-link>
<a @click.prevent="deleteService(service)" href="#" class="btn btn-danger"> <a v-if="$store.state.admin" @click.prevent="deleteService(service)" href="#" class="btn btn-danger">
<font-awesome-icon icon="times" /> <font-awesome-icon icon="times" />
</a> </a>
</div> </div>

View File

@ -14,17 +14,16 @@
<li @click="navopen = !navopen" class="nav-item navbar-item"> <li @click="navopen = !navopen" class="nav-item navbar-item">
<router-link to="/dashboard/services" class="nav-link">Services</router-link> <router-link to="/dashboard/services" class="nav-link">Services</router-link>
</li> </li>
<li @click="navopen = !navopen" class="nav-item navbar-item"> <li v-if="$store.state.admin" @click="navopen = !navopen" class="nav-item navbar-item">
<router-link to="/dashboard/users" class="nav-link">Users</router-link> <router-link to="/dashboard/users" class="nav-link">Users</router-link>
</li> </li>
<li @click="navopen = !navopen" class="nav-item navbar-item"> <li @click="navopen = !navopen" class="nav-item navbar-item">
<router-link to="/dashboard/messages" class="nav-link">Messages</router-link> <router-link to="/dashboard/messages" class="nav-link">Messages</router-link>
</li> </li>
<li v-if="$store.state.admin" @click="navopen = !navopen" class="nav-item navbar-item">
<li @click="navopen = !navopen" class="nav-item navbar-item">
<router-link to="/dashboard/settings" class="nav-link">Settings</router-link> <router-link to="/dashboard/settings" class="nav-link">Settings</router-link>
</li> </li>
<li @click="navopen = !navopen" class="nav-item navbar-item"> <li v-if="$store.state.admin" @click="navopen = !navopen" class="nav-item navbar-item">
<router-link to="/dashboard/logs" class="nav-link">Logs</router-link> <router-link to="/dashboard/logs" class="nav-link">Logs</router-link>
</li> </li>
@ -47,7 +46,7 @@
name: 'TopNav', name: 'TopNav',
data () { data () {
return { return {
navopen: false, navopen: false
} }
}, },
methods: { methods: {
@ -55,6 +54,7 @@
await Api.logout() await Api.logout()
this.$store.commit('setHasAllData', false) this.$store.commit('setHasAllData', false)
this.$store.commit('setToken', null) this.$store.commit('setToken', null)
this.$store.commit('setAdmin', false)
await this.$router.push('/') await this.$router.push('/')
} }
} }

View File

@ -3,7 +3,7 @@
<div v-for="(incident, i) in incidents" class="card contain-card text-black-50 bg-white mb-4"> <div v-for="(incident, i) in incidents" class="card contain-card text-black-50 bg-white mb-4">
<div class="card-header">Incident: {{incident.title}} <div class="card-header">Incident: {{incident.title}}
<button @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right"> <button v-if="IsAdmin()" @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right">
<font-awesome-icon icon="times" /> Delete <font-awesome-icon icon="times" /> Delete
</button></div> </button></div>
<div class="card-body bg-light pt-1"> <div class="card-body bg-light pt-1">
@ -15,7 +15,7 @@
</div> </div>
<div class="card contain-card text-black-50 bg-white mb-5"> <div v-if="IsAdmin()" class="card contain-card text-black-50 bg-white mb-5">
<div class="card-header">Create Incident for {{service.name}}</div> <div class="card-header">Create Incident for {{service.name}}</div>
<div class="card-body"> <div class="card-body">
<form @submit.prevent="createIncident"> <form @submit.prevent="createIncident">

View File

@ -60,8 +60,10 @@
if (auth.error) { if (auth.error) {
this.error = true this.error = true
} else if (auth.token) { } else if (auth.token) {
this.auth = Api.saveToken(this.username, auth.token) this.auth = Api.saveToken(this.username, auth.token, auth.admin)
this.$store.dispatch('loadAdmin') this.$store.dispatch('loadAdmin')
this.$store.commit('setAdmin', auth.admin)
window.console.log(auth)
this.$router.push('/dashboard') this.$router.push('/dashboard')
} }
this.loading = false this.loading = false

View File

@ -61,6 +61,9 @@ export default Vue.mixin({
isInt(n) { isInt(n) {
return n % 1 === 0; return n % 1 === 0;
}, },
isAdmin() {
return this.$store.state.admin
},
loggedIn() { loggedIn() {
const core = this.$store.getters.core const core = this.$store.getters.core
return core.logged_in === true return core.logged_in === true

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light"> <div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
<TopNav/> <TopNav :admin="$store.state.admin"/>
<router-view/> <router-view :admin="$store.state.admin"/>
</div> </div>
</template> </template>
@ -14,20 +14,14 @@
components: { components: {
TopNav, TopNav,
}, },
async mounted() {
if (this.$route.path !== "/login") {
try {
const u = await Api.users()
} catch (e) {
this.$router.push('/logout')
}
}
},
data () { data () {
return { return {
authenticated: false authenticated: false,
} }
}, },
async mounted() {
}
} }
</script> </script>

View File

@ -25,7 +25,8 @@ export default new Vuex.Store({
groups: [], groups: [],
messages: [], messages: [],
users: [], users: [],
notifiers: [] notifiers: [],
admin: false
}, },
getters: { getters: {
hasAllData: state => state.hasAllData, hasAllData: state => state.hasAllData,
@ -39,6 +40,8 @@ export default new Vuex.Store({
users: state => state.users, users: state => state.users,
notifiers: state => state.notifiers, notifiers: state => state.notifiers,
isAdmin: state => state.admin,
servicesInOrder: state => state.services.sort((a, b) => a.order_id - b.order_id), servicesInOrder: state => state.services.sort((a, b) => a.order_id - b.order_id),
groupsInOrder: state => state.groups.sort((a, b) => a.order_id - b.order_id), groupsInOrder: state => state.groups.sort((a, b) => a.order_id - b.order_id),
groupsClean: state => state.groups.filter(g => g.name !== '').sort((a, b) => a.order_id - b.order_id), groupsClean: state => state.groups.filter(g => g.name !== '').sort((a, b) => a.order_id - b.order_id),
@ -106,7 +109,10 @@ export default new Vuex.Store({
}, },
setNotifiers (state, notifiers) { setNotifiers (state, notifiers) {
state.notifiers = notifiers state.notifiers = notifiers
} },
setAdmin (state, admin) {
state.admin = admin
},
}, },
actions: { actions: {
async getAllServices(context) { async getAllServices(context) {

View File

@ -43,13 +43,12 @@ type apiResponse struct {
} }
func apiIndexHandler(r *http.Request) interface{} { func apiIndexHandler(r *http.Request) interface{} {
coreClone := core.App coreClone := *core.App
var loggedIn bool
_, err := getJwtToken(r) _, err := getJwtToken(r)
if err == nil { if err == nil {
loggedIn = true coreClone.LoggedIn = true
coreClone.IsAdmin = IsAdmin(r)
} }
coreClone.LoggedIn = loggedIn
return coreClone return coreClone
} }

View File

@ -212,12 +212,14 @@ func apiLoginHandler(w http.ResponseWriter, r *http.Request) {
user, auth := users.AuthUser(username, password) user, auth := users.AuthUser(username, password)
if auth { if auth {
utils.Log.Infoln(fmt.Sprintf("User %v logged in from IP %v", user.Username, r.RemoteAddr)) utils.Log.Infoln(fmt.Sprintf("User %v logged in from IP %v", user.Username, r.RemoteAddr))
_, token := setJwtToken(user, w) claim, token := setJwtToken(user, w)
resp := struct { resp := struct {
Token string `json:"token"` Token string `json:"token"`
IsAdmin bool `json:"admin"`
}{ }{
token, token,
claim.Admin,
} }
returnJson(resp, w, r) returnJson(resp, w, r)
} else { } else {

View File

@ -87,9 +87,9 @@ func Router() *mux.Router {
// API Routes // API Routes
r.Handle("/api", scoped(apiIndexHandler)) r.Handle("/api", scoped(apiIndexHandler))
r.Handle("/api/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
//r.Handle("/oauth/callback", http.HandlerFunc(OAuthRedirect)) //r.Handle("/oauth/callback", http.HandlerFunc(OAuthRedirect))
api.Handle("/api/login", http.HandlerFunc(apiLoginHandler)).Methods("POST") api.Handle("/api/login", http.HandlerFunc(apiLoginHandler)).Methods("POST")
r.Handle("/api/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
api.Handle("/api/logout", http.HandlerFunc(logoutHandler)) api.Handle("/api/logout", http.HandlerFunc(logoutHandler))
api.Handle("/api/renew", authenticated(apiRenewHandler, false)) api.Handle("/api/renew", authenticated(apiRenewHandler, false))
api.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET") api.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")

View File

@ -31,6 +31,7 @@ type Core struct {
UseCdn null.NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"` UseCdn null.NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"`
Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"` Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"`
LoggedIn bool `gorm:"-" json:"logged_in"` LoggedIn bool `gorm:"-" json:"logged_in"`
IsAdmin bool `gorm:"-" json:"admin"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
Started time.Time `gorm:"-" json:"started_on"` Started time.Time `gorm:"-" json:"started_on"`