new custom oAuth authentication method, added "local" auth method as default

pull/702/head
hunterlong 2020-06-25 21:46:09 -07:00
parent 202695ba20
commit 08e5d81c3c
9 changed files with 149 additions and 14 deletions

View File

@ -11,6 +11,7 @@
- Added Google oAuth email/domain user restrictions
- Modified notifiers to use dereferenced services and failures
- Added core.Example() function for testing
- Added Custom oAuth Authentication method
# 0.90.55 (06-18-2020)
- Added 404 page

View File

@ -37,6 +37,10 @@
<font-awesome-icon :icon="['fab', 'google']" /> Login with Google
</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>
</template>
@ -95,6 +99,9 @@
},
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`
},
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 : "" }`
}
}
}

View File

@ -168,6 +168,70 @@
</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">
<font-awesome-icon v-if="loading" icon="circle-notch" class="mr-2" spin/> Save OAuth Settings
</button>
@ -191,6 +255,7 @@
slack_enabled: false,
github_enabled: false,
local_enabled: false,
custom_enabled: false,
loading: false,
oauth: {
gh_client_id: "",
@ -204,7 +269,13 @@
slack_client_id: "",
slack_client_secret: "",
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.google_enabled = this.has('google')
this.slack_enabled = this.has('slack')
this.custom_enabled = this.has('custom')
},
methods: {
providers() {
@ -230,6 +302,9 @@
if (this.slack_enabled) {
providers.push("slack")
}
if (this.custom_enabled) {
providers.push("custom")
}
return providers.join(",")
},
has(val) {

View File

@ -29,6 +29,8 @@ func oauthHandler(w http.ResponseWriter, r *http.Request) {
oauth, err = githubOAuth(r)
case "slack":
oauth, err = slackOAuth(r)
case "custom":
oauth, err = customOAuth(r)
}
if err != nil {

40
handlers/oauth_custom.go Normal file
View File

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

View File

@ -20,6 +20,7 @@ func githubOAuth(r *http.Request) (*oAuth, error) {
ClientID: auth.GithubClientID,
ClientSecret: auth.GithubClientSecret,
Endpoint: github.Endpoint,
RedirectURL: core.App.Domain + basePath + "oauth/github",
}
gg, err := config.Exchange(r.Context(), code)

View File

@ -20,7 +20,7 @@ func googleOAuth(r *http.Request) (*oAuth, error) {
ClientID: auth.GoogleClientID,
ClientSecret: auth.GoogleClientSecret,
Endpoint: google.Endpoint,
RedirectURL: core.App.Domain + "/oauth/google",
RedirectURL: core.App.Domain + basePath + "oauth/google",
}
gg, err := config.Exchange(r.Context(), code)

View File

@ -28,6 +28,8 @@ func Samples() error {
apiSecret = utils.RandomString(32)
}
oauth := OAuth{Providers: "local"}
core := &Core{
Name: utils.Params.GetString("NAME"),
Description: utils.Params.GetString("DESCRIPTION"),
@ -38,6 +40,7 @@ func Samples() error {
Footer: null.NewNullString(""),
MigrationId: utils.Now().Unix(),
Language: utils.Params.GetString("LANGUAGE"),
OAuth: oauth,
}
return core.Create()

View File

@ -43,18 +43,24 @@ type Core struct {
}
type OAuth struct {
Providers string `gorm:"column:oauth_providers;" json:"oauth_providers"`
GithubClientID string `gorm:"column:gh_client_id" json:"gh_client_id"`
GithubClientSecret string `gorm:"column:gh_client_secret" json:"gh_client_secret" scope:"admin"`
GithubUsers string `gorm:"column:gh_users" json:"gh_users" scope:"admin"`
GithubOrgs string `gorm:"column:gh_orgs" json:"gh_orgs" scope:"admin"`
GoogleClientID string `gorm:"column:google_client_id" json:"google_client_id"`
GoogleClientSecret string `gorm:"column:google_client_secret" json:"google_client_secret" scope:"admin"`
GoogleUsers string `gorm:"column:google_users" json:"google_users" scope:"admin"`
SlackClientID string `gorm:"column:slack_client_id" json:"slack_client_id"`
SlackClientSecret string `gorm:"column:slack_client_secret" json:"slack_client_secret" scope:"admin"`
SlackTeam string `gorm:"column:slack_team" json:"slack_team" scope:"admin"`
SlackUsers string `gorm:"column:slack_users" json:"slack_users" scope:"admin"`
Providers string `gorm:"column:oauth_providers;" json:"oauth_providers"`
GithubClientID string `gorm:"column:gh_client_id" json:"gh_client_id"`
GithubClientSecret string `gorm:"column:gh_client_secret" json:"gh_client_secret" scope:"admin"`
GithubUsers string `gorm:"column:gh_users" json:"gh_users" scope:"admin"`
GithubOrgs string `gorm:"column:gh_orgs" json:"gh_orgs" scope:"admin"`
GoogleClientID string `gorm:"column:google_client_id" json:"google_client_id"`
GoogleClientSecret string `gorm:"column:google_client_secret" json:"google_client_secret" scope:"admin"`
GoogleUsers string `gorm:"column:google_users" json:"google_users" scope:"admin"`
SlackClientID string `gorm:"column:slack_client_id" json:"slack_client_id"`
SlackClientSecret string `gorm:"column:slack_client_secret" json:"slack_client_secret" scope:"admin"`
SlackTeam string `gorm:"column:slack_team" json:"slack_team" 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