mirror of https://github.com/statping/statping
new custom oAuth authentication method, added "local" auth method as default
parent
202695ba20
commit
08e5d81c3c
|
@ -11,6 +11,7 @@
|
||||||
- Added Google oAuth email/domain user restrictions
|
- Added Google oAuth email/domain user restrictions
|
||||||
- Modified notifiers to use dereferenced services and failures
|
- Modified notifiers to use dereferenced services and failures
|
||||||
- Added core.Example() function for testing
|
- Added core.Example() function for testing
|
||||||
|
- Added Custom oAuth Authentication method
|
||||||
|
|
||||||
# 0.90.55 (06-18-2020)
|
# 0.90.55 (06-18-2020)
|
||||||
- Added 404 page
|
- Added 404 page
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
<font-awesome-icon :icon="['fab', 'google']" /> Login with Google
|
<font-awesome-icon :icon="['fab', 'google']" /> Login with Google
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a v-if="oauth && oauth.custom_client_id" @click.prevent="Customlogin" href="#" class="btn btn-block btn-outline-dark">
|
||||||
|
<font-awesome-icon :icon="['fas', 'address-card']" /> Login with {{oauth.custom_name}}
|
||||||
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -95,6 +99,9 @@
|
||||||
},
|
},
|
||||||
Googlelogin() {
|
Googlelogin() {
|
||||||
window.location = `https://accounts.google.com/signin/oauth?client_id=${this.oauth.google_client_id}&redirect_uri=${this.core.domain}/oauth/google&response_type=code&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email`
|
window.location = `https://accounts.google.com/signin/oauth?client_id=${this.oauth.google_client_id}&redirect_uri=${this.core.domain}/oauth/google&response_type=code&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email`
|
||||||
|
},
|
||||||
|
Customlogin() {
|
||||||
|
window.location = `${this.oauth.custom_endpoint_auth}?client_id=${this.oauth.custom_client_id}&redirect_uri=${this.core.domain}/oauth/custom${this.oauth.custom_scopes !== "" ? "&scope="+this.oauth.custom_scopes : "" }`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,70 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card text-black-50 bg-white mb-3">
|
||||||
|
<div class="card-header">Custom oAuth Settings</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<label for="custom_name" class="col-sm-4 col-form-label">Custom Name</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input v-model="oauth.custom_name" type="text" class="form-control" id="custom_name" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<label for="custom_client" class="col-sm-4 col-form-label">Client ID</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input v-model="oauth.custom_client_id" type="text" class="form-control" id="custom_client" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="custom_secret" class="col-sm-4 col-form-label">Client Secret</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input v-model="oauth.custom_client_secret" type="text" class="form-control" id="custom_secret" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="custom_endpoint" class="col-sm-4 col-form-label">Auth Endpoint</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input v-model="oauth.custom_endpoint_auth" type="text" class="form-control" id="custom_endpoint" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="custom_endpoint_token" class="col-sm-4 col-form-label">Token Endpoint</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input v-model="oauth.custom_endpoint_token" type="text" class="form-control" id="custom_endpoint_token" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="custom_scopes" class="col-sm-4 col-form-label">Scopes</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input v-model="oauth.custom_scopes" type="text" class="form-control" id="custom_scopes">
|
||||||
|
<small>Optional comma delimited list of oauth scopes</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="switch-custom-oauth" class="col-sm-4 col-form-label">Enable Custom Login</label>
|
||||||
|
<div class="col-md-8 col-xs-12 mt-1">
|
||||||
|
<span @click="custom_enabled = !!custom_enabled" class="switch float-left">
|
||||||
|
<input v-model="custom_enabled" type="checkbox" class="switch" id="switch-custom-oauth" :checked="custom_enabled">
|
||||||
|
<label for="switch-custom-oauth"> </label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="slack_callback" class="col-sm-4 col-form-label">Callback URL</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="input-group">
|
||||||
|
<input v-bind:value="`${core.domain}/oauth/custom`" type="text" class="form-control" id="custom_callback" readonly>
|
||||||
|
<div class="input-group-append copy-btn">
|
||||||
|
<button @click.prevent="copy(`${core.domain}/oauth/custom`)" class="btn btn-outline-secondary" type="button">Copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<button class="btn btn-primary btn-block" @click.prevent="saveOAuth" type="submit" :disabled="loading">
|
<button class="btn btn-primary btn-block" @click.prevent="saveOAuth" type="submit" :disabled="loading">
|
||||||
<font-awesome-icon v-if="loading" icon="circle-notch" class="mr-2" spin/> Save OAuth Settings
|
<font-awesome-icon v-if="loading" icon="circle-notch" class="mr-2" spin/> Save OAuth Settings
|
||||||
</button>
|
</button>
|
||||||
|
@ -191,6 +255,7 @@
|
||||||
slack_enabled: false,
|
slack_enabled: false,
|
||||||
github_enabled: false,
|
github_enabled: false,
|
||||||
local_enabled: false,
|
local_enabled: false,
|
||||||
|
custom_enabled: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
oauth: {
|
oauth: {
|
||||||
gh_client_id: "",
|
gh_client_id: "",
|
||||||
|
@ -204,7 +269,13 @@
|
||||||
slack_client_id: "",
|
slack_client_id: "",
|
||||||
slack_client_secret: "",
|
slack_client_secret: "",
|
||||||
slack_team: "",
|
slack_team: "",
|
||||||
slack_users: ""
|
slack_users: "",
|
||||||
|
custom_name: "",
|
||||||
|
custom_client_id: "",
|
||||||
|
custom_client_secret: "",
|
||||||
|
custom_endpoint_auth: "",
|
||||||
|
custom_endpoint_token: "",
|
||||||
|
custom_scopes: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -214,6 +285,7 @@
|
||||||
this.github_enabled = this.has('github')
|
this.github_enabled = this.has('github')
|
||||||
this.google_enabled = this.has('google')
|
this.google_enabled = this.has('google')
|
||||||
this.slack_enabled = this.has('slack')
|
this.slack_enabled = this.has('slack')
|
||||||
|
this.custom_enabled = this.has('custom')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
providers() {
|
providers() {
|
||||||
|
@ -230,6 +302,9 @@
|
||||||
if (this.slack_enabled) {
|
if (this.slack_enabled) {
|
||||||
providers.push("slack")
|
providers.push("slack")
|
||||||
}
|
}
|
||||||
|
if (this.custom_enabled) {
|
||||||
|
providers.push("custom")
|
||||||
|
}
|
||||||
return providers.join(",")
|
return providers.join(",")
|
||||||
},
|
},
|
||||||
has(val) {
|
has(val) {
|
||||||
|
|
|
@ -29,6 +29,8 @@ func oauthHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
oauth, err = githubOAuth(r)
|
oauth, err = githubOAuth(r)
|
||||||
case "slack":
|
case "slack":
|
||||||
oauth, err = slackOAuth(r)
|
oauth, err = slackOAuth(r)
|
||||||
|
case "custom":
|
||||||
|
oauth, err = customOAuth(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/statping/statping/types/core"
|
||||||
|
"github.com/statping/statping/types/errors"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func customOAuth(r *http.Request) (*oAuth, error) {
|
||||||
|
auth := core.App.OAuth
|
||||||
|
code := r.URL.Query().Get("code")
|
||||||
|
|
||||||
|
scopes := strings.Split(auth.CustomScopes, ",")
|
||||||
|
|
||||||
|
config := &oauth2.Config{
|
||||||
|
ClientID: auth.CustomClientID,
|
||||||
|
ClientSecret: auth.CustomClientSecret,
|
||||||
|
Endpoint: oauth2.Endpoint{
|
||||||
|
AuthURL: auth.CustomEndpointAuth,
|
||||||
|
TokenURL: auth.CustomEndpointToken,
|
||||||
|
},
|
||||||
|
RedirectURL: core.App.Domain + basePath + "oauth/custom",
|
||||||
|
Scopes: scopes,
|
||||||
|
}
|
||||||
|
|
||||||
|
gg, err := config.Exchange(r.Context(), code)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !gg.Valid() {
|
||||||
|
return nil, errors.New("oauth token is not valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oAuth{
|
||||||
|
Token: gg,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ func githubOAuth(r *http.Request) (*oAuth, error) {
|
||||||
ClientID: auth.GithubClientID,
|
ClientID: auth.GithubClientID,
|
||||||
ClientSecret: auth.GithubClientSecret,
|
ClientSecret: auth.GithubClientSecret,
|
||||||
Endpoint: github.Endpoint,
|
Endpoint: github.Endpoint,
|
||||||
|
RedirectURL: core.App.Domain + basePath + "oauth/github",
|
||||||
}
|
}
|
||||||
|
|
||||||
gg, err := config.Exchange(r.Context(), code)
|
gg, err := config.Exchange(r.Context(), code)
|
||||||
|
|
|
@ -20,7 +20,7 @@ func googleOAuth(r *http.Request) (*oAuth, error) {
|
||||||
ClientID: auth.GoogleClientID,
|
ClientID: auth.GoogleClientID,
|
||||||
ClientSecret: auth.GoogleClientSecret,
|
ClientSecret: auth.GoogleClientSecret,
|
||||||
Endpoint: google.Endpoint,
|
Endpoint: google.Endpoint,
|
||||||
RedirectURL: core.App.Domain + "/oauth/google",
|
RedirectURL: core.App.Domain + basePath + "oauth/google",
|
||||||
}
|
}
|
||||||
|
|
||||||
gg, err := config.Exchange(r.Context(), code)
|
gg, err := config.Exchange(r.Context(), code)
|
||||||
|
|
|
@ -28,6 +28,8 @@ func Samples() error {
|
||||||
apiSecret = utils.RandomString(32)
|
apiSecret = utils.RandomString(32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oauth := OAuth{Providers: "local"}
|
||||||
|
|
||||||
core := &Core{
|
core := &Core{
|
||||||
Name: utils.Params.GetString("NAME"),
|
Name: utils.Params.GetString("NAME"),
|
||||||
Description: utils.Params.GetString("DESCRIPTION"),
|
Description: utils.Params.GetString("DESCRIPTION"),
|
||||||
|
@ -38,6 +40,7 @@ func Samples() error {
|
||||||
Footer: null.NewNullString(""),
|
Footer: null.NewNullString(""),
|
||||||
MigrationId: utils.Now().Unix(),
|
MigrationId: utils.Now().Unix(),
|
||||||
Language: utils.Params.GetString("LANGUAGE"),
|
Language: utils.Params.GetString("LANGUAGE"),
|
||||||
|
OAuth: oauth,
|
||||||
}
|
}
|
||||||
|
|
||||||
return core.Create()
|
return core.Create()
|
||||||
|
|
|
@ -43,18 +43,24 @@ type Core struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type OAuth struct {
|
type OAuth struct {
|
||||||
Providers string `gorm:"column:oauth_providers;" json:"oauth_providers"`
|
Providers string `gorm:"column:oauth_providers;" json:"oauth_providers"`
|
||||||
GithubClientID string `gorm:"column:gh_client_id" json:"gh_client_id"`
|
GithubClientID string `gorm:"column:gh_client_id" json:"gh_client_id"`
|
||||||
GithubClientSecret string `gorm:"column:gh_client_secret" json:"gh_client_secret" scope:"admin"`
|
GithubClientSecret string `gorm:"column:gh_client_secret" json:"gh_client_secret" scope:"admin"`
|
||||||
GithubUsers string `gorm:"column:gh_users" json:"gh_users" scope:"admin"`
|
GithubUsers string `gorm:"column:gh_users" json:"gh_users" scope:"admin"`
|
||||||
GithubOrgs string `gorm:"column:gh_orgs" json:"gh_orgs" scope:"admin"`
|
GithubOrgs string `gorm:"column:gh_orgs" json:"gh_orgs" scope:"admin"`
|
||||||
GoogleClientID string `gorm:"column:google_client_id" json:"google_client_id"`
|
GoogleClientID string `gorm:"column:google_client_id" json:"google_client_id"`
|
||||||
GoogleClientSecret string `gorm:"column:google_client_secret" json:"google_client_secret" scope:"admin"`
|
GoogleClientSecret string `gorm:"column:google_client_secret" json:"google_client_secret" scope:"admin"`
|
||||||
GoogleUsers string `gorm:"column:google_users" json:"google_users" scope:"admin"`
|
GoogleUsers string `gorm:"column:google_users" json:"google_users" scope:"admin"`
|
||||||
SlackClientID string `gorm:"column:slack_client_id" json:"slack_client_id"`
|
SlackClientID string `gorm:"column:slack_client_id" json:"slack_client_id"`
|
||||||
SlackClientSecret string `gorm:"column:slack_client_secret" json:"slack_client_secret" scope:"admin"`
|
SlackClientSecret string `gorm:"column:slack_client_secret" json:"slack_client_secret" scope:"admin"`
|
||||||
SlackTeam string `gorm:"column:slack_team" json:"slack_team" scope:"admin"`
|
SlackTeam string `gorm:"column:slack_team" json:"slack_team" scope:"admin"`
|
||||||
SlackUsers string `gorm:"column:slack_users" json:"slack_users" scope:"admin"`
|
SlackUsers string `gorm:"column:slack_users" json:"slack_users" scope:"admin"`
|
||||||
|
CustomName string `gorm:"column:custom_name" json:"custom_name"`
|
||||||
|
CustomClientID string `gorm:"column:custom_client_id" json:"custom_client_id"`
|
||||||
|
CustomClientSecret string `gorm:"column:custom_client_secret" json:"custom_client_secret" scope:"admin"`
|
||||||
|
CustomEndpointAuth string `gorm:"column:custom_endpoint_auth" json:"custom_endpoint_auth"`
|
||||||
|
CustomEndpointToken string `gorm:"column:custom_endpoint_token" json:"custom_endpoint_token" scope:"admin"`
|
||||||
|
CustomScopes string `gorm:"column:custom_scopes" json:"custom_scopes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllNotifiers contains all the Notifiers loaded
|
// AllNotifiers contains all the Notifiers loaded
|
||||||
|
|
Loading…
Reference in New Issue