oauth, incidents, fixes

pull/490/head
hunterlong 2020-04-07 04:53:32 -07:00
parent 3e791c2c74
commit d7190719e0
25 changed files with 379 additions and 119 deletions

View File

@ -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

View File

@ -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"}}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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>

View File

@ -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() {

View File

@ -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>

View File

@ -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,

View File

@ -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>

View File

@ -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,

View File

@ -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),

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -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)

View File

@ -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 {

98
handlers/oauth.go Normal file
View File

@ -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(),
}
}

View File

@ -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)

View File

@ -35,7 +35,6 @@ func TriggerSamples() error {
groups.Samples,
hits.Samples,
incidents.Samples,
incidents.SamplesUpdates,
)
}

View File

@ -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()
}

View File

@ -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

View File

@ -24,7 +24,7 @@ func Samples() error {
}
group3 := &Group{
Name: "Empty Group",
Name: "Private Services",
Public: null.NewNullBool(false),
Order: 3,
}

View File

@ -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()
}

View File

@ -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
}

View File

@ -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
}