mirror of https://github.com/statping/statping
oauth, incidents, fixes
parent
3e791c2c74
commit
d7190719e0
|
@ -1,6 +1,7 @@
|
|||
# 0.90.23
|
||||
- Added Incident Reporting
|
||||
- Added Cypress tests
|
||||
- Added Github and Google OAuth login (beta)
|
||||
|
||||
# 0.90.22
|
||||
- Added range input types for integer form fields
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col" class="d-none d-md-table-cell"></th>
|
||||
<th scope="col" class="d-none d-md-table-cell">Visibility</th>
|
||||
<th scope="col" class="d-none d-md-table-cell">Group</th>
|
||||
<th scope="col"></th>
|
||||
|
@ -16,9 +15,6 @@
|
|||
<font-awesome-icon icon="bars" class="mr-3"/>
|
||||
</span> {{service.name}}
|
||||
</td>
|
||||
<td v-if="$store.state.admin" class="d-none d-md-table-cell">
|
||||
<ToggleSwitch v-if="service.online" :service="service"/>
|
||||
</td>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<span class="badge" :class="{'badge-primary': service.public, 'badge-secondary': !service.public}">
|
||||
{{service.public ? "PUBLIC" : "PRIVATE"}}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<template>
|
||||
<div class="row mt-4">
|
||||
<div v-for="(incident, i) in incidents" class="col-12">
|
||||
<h6><span class="badge badge-secondary">New</span>
|
||||
{{incident.title}}
|
||||
<span class="font-2">{{incident.created_at}}</span>
|
||||
</h6>
|
||||
<div class="row">
|
||||
<div v-for="(incident, i) in incidents" class="col-12 mt-4">
|
||||
<h5>Incident: {{incident.title}}<span class="font-2 float-right">{{niceDate(incident.created_at)}}</span></h5>
|
||||
{{incident.description}}
|
||||
{{incident}}
|
||||
<div class="row">
|
||||
<div v-for="(update, i) in incident.updates.reverse()" v-bind:key="update.id" class="col-12 mt-3">
|
||||
<span class="col-2 badge text-uppercase" :class="badgeClass(update.type)">{{update.type}}</span>
|
||||
<span class="col-10">{{update.message}}</span>
|
||||
<span class="col-12 font-1 float-right text-black-50">{{ago(update.created_at)}} ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -30,10 +33,17 @@ export default {
|
|||
this.getIncidents()
|
||||
},
|
||||
methods: {
|
||||
async getIncidents() {
|
||||
this.incidents = await Api.incidents_service(this.service)
|
||||
badgeClass(val) {
|
||||
switch (val.toLowerCase()) {
|
||||
case "resolved":
|
||||
return "badge-success"
|
||||
case "update":
|
||||
return "badge-info"
|
||||
case "investigating":
|
||||
return "badge-danger"
|
||||
}
|
||||
},
|
||||
async getIncidentsUpdates() {
|
||||
async getIncidents() {
|
||||
this.incidents = await Api.incidents_service(this.service)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,37 +50,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row d-none">
|
||||
<div class="col-12">
|
||||
<h4 class="mt-5">Github Authentication</h4>
|
||||
|
||||
<div class="form-group row d-none">
|
||||
<label class="col-sm-4 col-form-label">Github Client ID</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="core.github_clientId" type="text" class="form-control" placeholder="" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">Github Client Secret</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="core.github_clientScret" type="text" class="form-control" placeholder="" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="switch-group-public" class="col-sm-4 col-form-label">Enabled</label>
|
||||
<div class="col-md-8 col-xs-12 mt-1">
|
||||
<span class="switch float-left">
|
||||
<input type="checkbox" class="switch" id="switch-group-public">
|
||||
<label for="switch-group-public">Enabled Github Auth</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button @click.prevent="saveSettings" type="submit" class="btn btn-primary btn-block">Save Settings</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
@ -98,12 +67,7 @@
|
|||
methods: {
|
||||
async saveSettings() {
|
||||
const c = this.core
|
||||
const coreForm = {
|
||||
name: c.name, description: c.description, domain: c.domain,
|
||||
timezone: c.timezone, using_cdn: c.using_cdn, footer: c.footer, update_notify: c.update_notify,
|
||||
gh_client_id: c.github_clientId, gh_client_secret: c.github_clientSecret
|
||||
};
|
||||
await Api.core_save(coreForm)
|
||||
await Api.core_save(c)
|
||||
const core = await Api.core()
|
||||
this.$store.commit('setCore', core)
|
||||
this.core = core
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
<div class="card-header">Incident: {{incident.title}}
|
||||
<button @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right">
|
||||
<font-awesome-icon icon="times" /> Delete
|
||||
</button></div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="card-body bg-light pt-1">
|
||||
|
||||
<FormIncidentUpdates :incident="incident"/>
|
||||
|
||||
<span class="font-2">Created: {{niceDate(incident.created_at)}} | Last Update: {{niceDate(incident.updated_at)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<a v-if="oauth.oauth_providers.split(',').includes('github')" class="btn btn-block btn-outline-dark" :href="`https://github.com/login/oauth/authorize?scope=user:email&client_id=${oauth.gh_client_id}`">Login with Github</a>
|
||||
<a v-if="oauth.oauth_providers.split(',').includes('google')" class="btn btn-block btn-outline-secondary" :href="`https://oauth-redirect.googleusercontent.com/r/${oauth.google_client_id}`">Login with Google</a>
|
||||
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
@ -31,6 +34,11 @@
|
|||
|
||||
export default {
|
||||
name: 'FormLogin',
|
||||
props: {
|
||||
oauth: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
username: "",
|
||||
|
@ -38,8 +46,7 @@
|
|||
auth: {},
|
||||
loading: false,
|
||||
error: false,
|
||||
disabled: true,
|
||||
ghLoginURL: ""
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<form @submit.prevent="saveOAuth">
|
||||
<div class="card text-black-50 bg-white mb-3">
|
||||
<div class="card-header">Internal Login</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label for="switch-gh-oauth" class="col-sm-4 col-form-label">OAuth Login Settings</label>
|
||||
<div class="col-md-8 col-xs-12 mt-1">
|
||||
<span @click="internal_enabled = !!internal_enabled" class="switch float-left">
|
||||
<input v-model="internal_enabled" type="checkbox" class="switch" id="switch-local-oauth" :checked="internal_enabled">
|
||||
<label for="switch-local-oauth">Use email/password Authentication</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="whitelist_domains" class="col-sm-4 col-form-label">Whitelist Domains</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="oauth.oauth_domains" type="text" class="form-control" placeholder="domain.com" id="whitelist_domains">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-black-50 bg-white mb-3">
|
||||
<div class="card-header">Github Settings</div>
|
||||
<div class="card-body">
|
||||
<span>You will need to create a new <a href="https://github.com/settings/developers">OAuth App</a> within Github.</span>
|
||||
|
||||
<div class="form-group row mt-3">
|
||||
<label for="github_client" class="col-sm-4 col-form-label">Github Client ID</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="oauth.gh_client_id" type="text" class="form-control" id="github_client" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="github_secret" class="col-sm-4 col-form-label">Github Client Secret</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="oauth.gh_client_secret" type="text" class="form-control" id="github_secret" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="switch-gh-oauth" class="col-sm-4 col-form-label">Enable Github Login</label>
|
||||
<div class="col-md-8 col-xs-12 mt-1">
|
||||
<span @click="github_enabled = !!github_enabled" class="switch float-left">
|
||||
<input v-model="github_enabled" type="checkbox" class="switch" id="switch-gh-oauth" :checked="github_enabled">
|
||||
<label for="switch-gh-oauth"> </label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<small class="form-text text-muted">Authorized Callback URL</small>
|
||||
<input v-bind:value="`${$store.getters.core.domain}/oauth/github`" type="text" class="form-control" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-black-50 bg-white mb-3">
|
||||
<div class="card-header">Google Settings</div>
|
||||
<div class="card-body">
|
||||
<span>Go to <a href="https://console.cloud.google.com/apis/credentials">OAuth Consent Screen</a> on Google Console to create a new OAuth application.</span>
|
||||
|
||||
<div class="form-group row mt-3">
|
||||
<label for="github_client" class="col-sm-4 col-form-label">Google Client ID</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="oauth.google_client_id" type="text" class="form-control" id="google_client" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="github_secret" class="col-sm-4 col-form-label">Google Client Secret</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="oauth.google_client_secret" type="text" class="form-control" id="google_secret" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="switch-google-oauth" class="col-sm-4 col-form-label">Enable Google Login</label>
|
||||
<div class="col-md-8 col-xs-12 mt-1">
|
||||
<span @click="google_enabled = !!google_enabled" class="switch float-left">
|
||||
<input v-model="google_enabled" type="checkbox" class="switch" id="switch-google-oauth" :checked="google_enabled">
|
||||
<label for="switch-google-oauth"> </label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<small class="form-text text-muted">Authorized Redirect URI</small>
|
||||
<input v-bind:value="`${$store.getters.core.domain}/oauth/google`" type="text" class="form-control" readonly>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-block" @click.prevent="saveOAuth" type="submit">
|
||||
Save OAuth Settings
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Api from "../API";
|
||||
|
||||
export default {
|
||||
name: 'OAuth',
|
||||
props: {
|
||||
oauth: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
internal_enabled: this.$store.getters.core.oauth.oauth_providers.split(",").includes('local'),
|
||||
google_enabled: this.$store.getters.core.oauth.oauth_providers.split(",").includes('google'),
|
||||
github_enabled: this.$store.getters.core.oauth.oauth_providers.split(",").includes('github')
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
// this.github_enabled = this.$store.getters.core.oauth.oauth_providers.split(",").includes('github')
|
||||
// const c = await Api.core()
|
||||
// this.auth = c.auth
|
||||
},
|
||||
methods: {
|
||||
providers() {
|
||||
let providers = [];
|
||||
if (this.github_enabled) {
|
||||
providers.push("github")
|
||||
}
|
||||
if (this.internal_enabled) {
|
||||
providers.push("local")
|
||||
}
|
||||
return providers.join(",")
|
||||
},
|
||||
async saveOAuth() {
|
||||
let c = this.$store.getters.core
|
||||
c.oauth = this.oauth
|
||||
c.oauth.oauth_providers = this.providers()
|
||||
await Api.core_save(c)
|
||||
const core = await Api.core()
|
||||
this.$store.commit('setCore', core)
|
||||
this.core = core
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
</style>
|
|
@ -3,6 +3,19 @@
|
|||
|
||||
<Header/>
|
||||
|
||||
<div v-for="(service, i) in $store.getters.servicesNoGroup" class="col-12 full-col-12">
|
||||
<div class="list-group online_list mb-4">
|
||||
<a class="service_li list-group-item list-group-item-action">
|
||||
<router-link class="no-decoration font-3" :to="serviceLink(service)">{{service.name}}</router-link>
|
||||
<span class="badge float-right" :class="{'bg-success': service.online, 'bg-danger': !service.online }">{{service.online ? "ONLINE" : "OFFLINE"}}</span>
|
||||
|
||||
<GroupServiceFailures :service="service"/>
|
||||
|
||||
<IncidentsBlock :service="service"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="(group, index) in $store.getters.groupsInOrder" v-bind:key="index">
|
||||
<Group :group=group />
|
||||
</div>
|
||||
|
@ -26,11 +39,15 @@ import Group from '../components/Index/Group';
|
|||
import Header from '../components/Index/Header';
|
||||
import MessageBlock from '../components/Index/MessageBlock';
|
||||
import ServiceBlock from '../components/Service/ServiceBlock';
|
||||
import GroupServiceFailures from "../components/Index/GroupServiceFailures";
|
||||
import IncidentsBlock from "../components/Index/IncidentsBlock";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
IncidentsBlock,
|
||||
GroupServiceFailures,
|
||||
ServiceBlock,
|
||||
MessageBlock,
|
||||
Group,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<img alt="Statping Login" class="col-12 mt-5 mt-md-0" style="max-width:680px" src="banner.png">
|
||||
</div>
|
||||
|
||||
<FormLogin/>
|
||||
<FormLogin :oauth="$store.getters.core.oauth"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
<a @click.prevent="changeTab" class="nav-link" v-bind:class="{active: liClass('v-pills-cache-tab')}" id="v-pills-cache-tab" data-toggle="pill" href="#v-pills-cache" role="tab" aria-controls="v-pills-cache" aria-selected="false">
|
||||
<font-awesome-icon icon="paperclip" class="mr-2"/> Cache
|
||||
</a>
|
||||
<a @click.prevent="changeTab" class="nav-link" v-bind:class="{active: liClass('v-pills-oauth-tab')}" id="v-pills-oauth-tab" data-toggle="pill" href="#v-pills-oauth" role="tab" aria-controls="v-pills-oauth" aria-selected="false">
|
||||
<font-awesome-icon icon="key" class="mr-2"/> OAuth <span class="mt-1 float-right badge badge-light text-dark font-1">BETA</span>
|
||||
</a>
|
||||
|
||||
<h6 class="mt-4 text-muted">Notifiers</h6>
|
||||
|
||||
|
@ -42,6 +45,10 @@
|
|||
<font-awesome-icon icon="code-branch" class="mr-3"/> Statping Github Repo
|
||||
</a>
|
||||
|
||||
<div class="row justify-content-center mt-2">
|
||||
<github-button href="https://github.com/statping/statping" data-icon="octicon-star" data-show-count="true" aria-label="Star Statping on GitHub">Star</github-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -53,9 +60,7 @@
|
|||
<div class="card text-black-50 bg-white mb-5">
|
||||
<div class="card-header">Statping Settings</div>
|
||||
<div class="card-body">
|
||||
|
||||
<CoreSettings :core="core"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -101,6 +106,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" v-bind:class="{active: liClass('v-pills-oauth-tab'), show: liClass('v-pills-oauth-tab')}" id="v-pills-oauth" role="tabpanel" aria-labelledby="v-pills-oauth-tab">
|
||||
<OAuth :oauth="core.oauth"/>
|
||||
</div>
|
||||
|
||||
<div v-for="(notifier, index) in $store.getters.notifiers" v-bind:key="`${notifier.title}_${index}`" class="tab-pane fade" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), show: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" role="tabpanel" v-bind:aria-labelledby="`v-pills-${notifier.method.toLowerCase()}-tab`">
|
||||
<Notifier :notifier="notifier"/>
|
||||
</div>
|
||||
|
@ -119,10 +128,14 @@
|
|||
import Notifier from "../forms/Notifier";
|
||||
import ThemeEditor from "../components/Dashboard/ThemeEditor";
|
||||
import Cache from "@/components/Dashboard/Cache";
|
||||
import OAuth from "../forms/OAuth";
|
||||
import GithubButton from 'vue-github-button'
|
||||
|
||||
export default {
|
||||
name: 'Settings',
|
||||
components: {
|
||||
GithubButton,
|
||||
OAuth,
|
||||
Cache,
|
||||
ThemeEditor,
|
||||
FormIntegration,
|
||||
|
|
|
@ -43,6 +43,7 @@ export default new Vuex.Store({
|
|||
isAdmin: state => state.admin,
|
||||
|
||||
servicesInOrder: state => state.services.sort((a, b) => a.order_id - b.order_id),
|
||||
servicesNoGroup: state => state.services.filter(g => g.group_id === 0).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),
|
||||
groupsCleanInOrder: state => state.groups.filter(g => g.name !== '').sort((a, b) => a.order_id - b.order_id).sort((a, b) => a.order_id - b.order_id),
|
||||
|
|
|
@ -7,6 +7,10 @@ module.exports = {
|
|||
'/api': {
|
||||
logLevel: 'debug',
|
||||
target: 'http://0.0.0.0:8585'
|
||||
},
|
||||
'/oauth': {
|
||||
logLevel: 'debug',
|
||||
target: 'http://0.0.0.0:8585'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -23,6 +23,7 @@ require (
|
|||
github.com/stretchr/testify v1.5.1
|
||||
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
|
||||
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
golang.org/x/tools v0.0.0-20200321014904-268ba720d32c // indirect
|
||||
google.golang.org/grpc v1.28.0
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1,3 +1,4 @@
|
|||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
|
@ -274,6 +275,7 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k
|
|||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
|
@ -79,6 +79,7 @@ func apiCoreHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if c.Timezone != app.Timezone {
|
||||
app.Timezone = c.Timezone
|
||||
}
|
||||
app.OAuth = c.OAuth
|
||||
app.UseCdn = null.NewNullBool(c.UseCdn.Bool)
|
||||
err = app.Update()
|
||||
returnJson(core.App, w, r)
|
||||
|
|
|
@ -248,32 +248,6 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
|
|||
}
|
||||
}
|
||||
|
||||
// executeJSResponse will render a Javascript response
|
||||
func executeJSResponse(w http.ResponseWriter, r *http.Request, file string, data interface{}) {
|
||||
//render, err := source.JsBox.String(file)
|
||||
//if err != nil {
|
||||
// log.Errorln(err)
|
||||
//}
|
||||
//if usingSSL {
|
||||
// w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
|
||||
//}
|
||||
//t := template.New("charts")
|
||||
//t.Funcs(template.FuncMap{
|
||||
// "safe": func(html string) template.HTML {
|
||||
// return template.HTML(html)
|
||||
// },
|
||||
// "Services": func() []services.ServiceInterface {
|
||||
// return core.CoreApp.Services
|
||||
// },
|
||||
//})
|
||||
//if _, err := t.Parse(render); err != nil {
|
||||
// log.Errorln(err)
|
||||
//}
|
||||
//if err := t.Execute(w, data); err != nil {
|
||||
// log.Errorln(err)
|
||||
//}
|
||||
}
|
||||
|
||||
func returnJson(d interface{}, w http.ResponseWriter, r *http.Request, statusCode ...int) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if len(statusCode) != 0 {
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/statping/statping/types/core"
|
||||
"github.com/statping/statping/types/null"
|
||||
"github.com/statping/statping/types/users"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/github"
|
||||
"golang.org/x/oauth2/google"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type oAuth struct {
|
||||
Email string
|
||||
Token string
|
||||
RefreshToken string
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func oauthHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
provider := vars["provider"]
|
||||
|
||||
var err error
|
||||
var oauth *oAuth
|
||||
switch provider {
|
||||
case "google":
|
||||
err, oauth = googleOAuth(r)
|
||||
case "github":
|
||||
err, oauth = githubOAuth(r)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
oauthLogin(oauth, w, r)
|
||||
}
|
||||
|
||||
func oauthLogin(oauth *oAuth, w http.ResponseWriter, r *http.Request) {
|
||||
user := &users.User{
|
||||
Id: 0,
|
||||
Username: oauth.Email,
|
||||
Email: oauth.Email,
|
||||
Admin: null.NewNullBool(true),
|
||||
}
|
||||
log.Infoln(fmt.Sprintf("OAuth User %v logged in from IP %v", oauth.Email, r.RemoteAddr))
|
||||
setJwtToken(user, w)
|
||||
|
||||
http.Redirect(w, r, basePath+"dashboard", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func githubOAuth(r *http.Request) (error, *oAuth) {
|
||||
c := *core.App
|
||||
code := r.URL.Query().Get("code")
|
||||
|
||||
config := &oauth2.Config{
|
||||
ClientID: c.OAuth.GithubClientID,
|
||||
ClientSecret: c.OAuth.GithubClientSecret,
|
||||
Endpoint: github.Endpoint,
|
||||
}
|
||||
|
||||
gg, err := config.Exchange(r.Context(), code)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
|
||||
return nil, &oAuth{
|
||||
Token: gg.AccessToken,
|
||||
RefreshToken: gg.RefreshToken,
|
||||
Valid: gg.Valid(),
|
||||
}
|
||||
}
|
||||
|
||||
func googleOAuth(r *http.Request) (error, *oAuth) {
|
||||
c := *core.App
|
||||
code := r.URL.Query().Get("code")
|
||||
|
||||
config := &oauth2.Config{
|
||||
ClientID: c.OAuth.GithubClientID,
|
||||
ClientSecret: c.OAuth.GithubClientSecret,
|
||||
Endpoint: google.Endpoint,
|
||||
}
|
||||
|
||||
gg, err := config.Exchange(r.Context(), code)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
|
||||
return nil, &oAuth{
|
||||
Token: gg.AccessToken,
|
||||
RefreshToken: gg.RefreshToken,
|
||||
Valid: gg.Valid(),
|
||||
}
|
||||
}
|
|
@ -72,7 +72,6 @@ func Router() *mux.Router {
|
|||
// API Routes
|
||||
r.Handle("/api", scoped(apiIndexHandler))
|
||||
r.Handle("/api/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
|
||||
//r.Handle("/oauth/callback", http.HandlerFunc(OAuthRedirect))
|
||||
api.Handle("/api/login", http.HandlerFunc(apiLoginHandler)).Methods("POST")
|
||||
api.Handle("/api/logout", http.HandlerFunc(logoutHandler))
|
||||
api.Handle("/api/renew", authenticated(apiRenewHandler, false))
|
||||
|
@ -160,6 +159,7 @@ func Router() *mux.Router {
|
|||
// API Generic Routes
|
||||
r.Handle("/metrics", readOnly(prometheusHandler, false))
|
||||
r.Handle("/health", http.HandlerFunc(healthCheckHandler))
|
||||
r.Handle("/oauth/{provider}", http.HandlerFunc(oauthHandler))
|
||||
r.Handle("/.well-known/", http.StripPrefix("/.well-known/", http.FileServer(http.Dir(dir+"/.well-known"))))
|
||||
|
||||
r.NotFoundHandler = http.HandlerFunc(error404Handler)
|
||||
|
|
|
@ -35,7 +35,6 @@ func TriggerSamples() error {
|
|||
groups.Samples,
|
||||
hits.Samples,
|
||||
incidents.Samples,
|
||||
incidents.SamplesUpdates,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ func (c *Core) Create() error {
|
|||
}
|
||||
|
||||
func (c *Core) Update() error {
|
||||
q := db.Update(c)
|
||||
q := db.UpdateColumns(c)
|
||||
return q.Error()
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ func New(version string) {
|
|||
// will be saved into 1 row in the 'core' table. You can use the core.CoreApp
|
||||
// global variable to interact with the attributes to the application, such as services.
|
||||
type Core struct {
|
||||
Name string `gorm:"not null;column:name" json:"name"`
|
||||
Name string `gorm:"not null;column:name" json:"name,omitempty"`
|
||||
Description string `gorm:"not null;column:description" json:"description,omitempty"`
|
||||
ConfigFile string `gorm:"column:config" json:"-"`
|
||||
ApiKey string `gorm:"column:api_key" json:"api_key" scope:"admin"`
|
||||
|
@ -38,16 +38,19 @@ type Core struct {
|
|||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
|
||||
Started time.Time `gorm:"-" json:"started_on"`
|
||||
Image string `gorm:"image" json:"started_on"`
|
||||
Notifications []AllNotifiers `gorm:"-" json:"-"`
|
||||
Integrations []Integrator `gorm:"-" json:"-"`
|
||||
|
||||
GHAuth
|
||||
OAuth `json:"oauth"`
|
||||
}
|
||||
|
||||
type GHAuth struct {
|
||||
GithubClientID string `gorm:"gh_client_id" json:"gh_client_id"`
|
||||
GithubClientSecret string `gorm:"gh_client_secret" json:"-"`
|
||||
type OAuth struct {
|
||||
Domains string `gorm:"column:oauth_domains" json:"oauth_domains,omitempty" scope:"admin"`
|
||||
Providers string `gorm:"column:oauth_providers;default:local" json:"oauth_providers,omitempty"`
|
||||
GithubClientID string `gorm:"column:gh_client_id" json:"gh_client_id,omitempty" scope:"admin"`
|
||||
GithubClientSecret string `gorm:"column:gh_client_secret" json:"gh_client_secret,omitempty" scope:"admin"`
|
||||
GoogleClientID string `gorm:"column:google_client_id" json:"google_client_id,omitempty" scope:"admin"`
|
||||
GoogleClientSecret string `gorm:"column:google_client_secret" json:"google_client_secret,omitempty" scope:"admin"`
|
||||
}
|
||||
|
||||
// AllNotifiers contains all the Notifiers loaded
|
||||
|
|
|
@ -24,7 +24,7 @@ func Samples() error {
|
|||
}
|
||||
|
||||
group3 := &Group{
|
||||
Name: "Empty Group",
|
||||
Name: "Private Services",
|
||||
Public: null.NewNullBool(false),
|
||||
Order: 3,
|
||||
}
|
||||
|
|
|
@ -2,22 +2,22 @@ package incidents
|
|||
|
||||
func (i *Incident) Updates() []*IncidentUpdate {
|
||||
var updates []*IncidentUpdate
|
||||
db.Model(&IncidentUpdate{}).Where("incident = ?", i.Id).Find(&updates)
|
||||
dbUpdate.Where("incident = ?", i.Id).Find(&updates)
|
||||
i.AllUpdates = updates
|
||||
return updates
|
||||
}
|
||||
|
||||
func (i *IncidentUpdate) Create() error {
|
||||
q := db.Create(i)
|
||||
q := dbUpdate.Create(i)
|
||||
return q.Error()
|
||||
}
|
||||
|
||||
func (i *IncidentUpdate) Update() error {
|
||||
q := db.Update(i)
|
||||
q := dbUpdate.Update(i)
|
||||
return q.Error()
|
||||
}
|
||||
|
||||
func (i *IncidentUpdate) Delete() error {
|
||||
q := db.Delete(i)
|
||||
q := dbUpdate.Delete(i)
|
||||
return q.Error()
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
|
||||
func Samples() error {
|
||||
incident1 := &Incident{
|
||||
Title: "Github Downtime",
|
||||
Description: "This is an example of a incident for a service.",
|
||||
Title: "Github Issues",
|
||||
Description: "There are new features for Statping, if you have any issues please visit the Github Repo.",
|
||||
ServiceId: 2,
|
||||
}
|
||||
if err := incident1.Create(); err != nil {
|
||||
|
@ -24,16 +24,12 @@ func Samples() error {
|
|||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SamplesUpdates() error {
|
||||
t := utils.Now()
|
||||
|
||||
i1 := &IncidentUpdate{
|
||||
IncidentId: 1,
|
||||
Message: "Github's page for Statping seems to be sending a 501 error.",
|
||||
Type: "Investigating",
|
||||
IncidentId: incident1.Id,
|
||||
Message: "Github seems be be having an issue right now.",
|
||||
Type: "investigating",
|
||||
CreatedAt: t.Add(-60 * time.Minute),
|
||||
}
|
||||
if err := i1.Create(); err != nil {
|
||||
|
@ -41,9 +37,9 @@ func SamplesUpdates() error {
|
|||
}
|
||||
|
||||
i2 := &IncidentUpdate{
|
||||
IncidentId: 1,
|
||||
Message: "Problem is continuing and we are looking at the issues.",
|
||||
Type: "Update",
|
||||
IncidentId: incident1.Id,
|
||||
Message: "Problem is continuing and we are looking at the issue.",
|
||||
Type: "update",
|
||||
CreatedAt: t.Add(-30 * time.Minute),
|
||||
}
|
||||
if err := i2.Create(); err != nil {
|
||||
|
@ -51,7 +47,7 @@ func SamplesUpdates() error {
|
|||
}
|
||||
|
||||
i3 := &IncidentUpdate{
|
||||
IncidentId: 1,
|
||||
IncidentId: incident1.Id,
|
||||
Message: "Github is now back online and everything is working.",
|
||||
Type: "Resolved",
|
||||
CreatedAt: t.Add(-5 * time.Minute),
|
||||
|
@ -61,9 +57,9 @@ func SamplesUpdates() error {
|
|||
}
|
||||
|
||||
u1 := &IncidentUpdate{
|
||||
IncidentId: 2,
|
||||
Message: "Github is now back online and everything is working.",
|
||||
Type: "Resolved",
|
||||
IncidentId: incident2.Id,
|
||||
Message: "Github is acting odd, probably getting DDOS-ed by China.",
|
||||
Type: "investigating",
|
||||
CreatedAt: t.Add(-120 * time.Minute),
|
||||
}
|
||||
if err := u1.Create(); err != nil {
|
||||
|
@ -71,13 +67,25 @@ func SamplesUpdates() error {
|
|||
}
|
||||
|
||||
u2 := &IncidentUpdate{
|
||||
IncidentId: 2,
|
||||
Message: "Github is now back online and everything is working.",
|
||||
Type: "Resolved",
|
||||
IncidentId: incident2.Id,
|
||||
Message: "Still seems to be an issue",
|
||||
Type: "update",
|
||||
CreatedAt: t.Add(-60 * time.Minute),
|
||||
}
|
||||
|
||||
if err := u2.Create(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u3 := &IncidentUpdate{
|
||||
IncidentId: incident2.Id,
|
||||
Message: "Github is now back online and everything is working.",
|
||||
Type: "resolved",
|
||||
CreatedAt: t.Add(-5 * time.Minute),
|
||||
}
|
||||
if err := u3.Create(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func Samples() error {
|
|||
Method: "GET",
|
||||
Timeout: 20,
|
||||
Order: 2,
|
||||
Public: null.NewNullBool(false),
|
||||
Public: null.NewNullBool(true),
|
||||
Permalink: null.NewNullString("statping_github"),
|
||||
VerifySSL: null.NewNullBool(true),
|
||||
NotifyAfter: 1,
|
||||
|
@ -103,5 +103,20 @@ func Samples() error {
|
|||
return err
|
||||
}
|
||||
|
||||
s6 := &Service{
|
||||
Name: "Private Service",
|
||||
Domain: "https://push.statping.com",
|
||||
Interval: 30,
|
||||
Type: "http",
|
||||
Timeout: 120,
|
||||
Order: 6,
|
||||
Public: null.NewNullBool(false),
|
||||
GroupId: 3,
|
||||
CreatedAt: createdOn,
|
||||
}
|
||||
if err := s6.Create(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue