..
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
auth "github.com/abbot/go-http-auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -108,11 +110,11 @@ func (h *HttpServer) doaction(w http.ResponseWriter, r *http.Request, params *Ad
|
|||||||
|
|
||||||
case "add":
|
case "add":
|
||||||
host := r.URL.Query().Get("host")
|
host := r.URL.Query().Get("host")
|
||||||
_, err := h._database.CreateHost(host)
|
pw, _, err := h._database.CreateHost(host)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
params.Alerts = append(params.Alerts, Alert{
|
params.Alerts = append(params.Alerts, Alert{
|
||||||
Type: "success",
|
Type: "success",
|
||||||
Message: fmt.Sprintf("created host %s", host),
|
Message: fmt.Sprintf("created host %s\npassword: %s", host, pw),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
params.Alerts = append(params.Alerts, Alert{
|
params.Alerts = append(params.Alerts, Alert{
|
||||||
@@ -154,6 +156,7 @@ func (h *HttpServer) adminPage(w http.ResponseWriter, r *http.Request) {
|
|||||||
params.Alerts = make([]Alert, 0)
|
params.Alerts = make([]Alert, 0)
|
||||||
params.Hosts = make(map[string]string)
|
params.Hosts = make(map[string]string)
|
||||||
params.IpAddresses = h._ipAddresses
|
params.IpAddresses = h._ipAddresses
|
||||||
|
params.LogoutUrl = h._oauth.LogoutUrl
|
||||||
|
|
||||||
|
|
||||||
h.doaction(w,r, params)
|
h.doaction(w,r, params)
|
||||||
@@ -161,8 +164,7 @@ func (h *HttpServer) adminPage(w http.ResponseWriter, r *http.Request) {
|
|||||||
claims, _ := h._oauth.GetClaims(w, token)
|
claims, _ := h._oauth.GetClaims(w, token)
|
||||||
|
|
||||||
|
|
||||||
params.Email = claims.Email
|
params.Claims = *claims
|
||||||
params.Profile = claims.Profile
|
|
||||||
|
|
||||||
if settings.FilterString != nil {
|
if settings.FilterString != nil {
|
||||||
params.Hosts = h._database.GetExistingHosts(*settings.FilterString)
|
params.Hosts = h._database.GetExistingHosts(*settings.FilterString)
|
||||||
@@ -275,13 +277,35 @@ func (h *HttpServer) updateHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Info("authorization successful.")
|
log.Info("authorization successful.")
|
||||||
log.Info("will update host ", host, " ip ", myip)
|
log.Info("will update host ", host, " ip ", myip)
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
|
if !h._database.ExistHost(host) {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
err := h._dnsclient.Update(host, myip)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpServer) Listen() {
|
func (h *HttpServer) Listen() {
|
||||||
h._server.ListenAndServe()
|
h._server.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Secret(user, realm string) string {
|
||||||
|
if user == "john" {
|
||||||
|
// password is "hello"
|
||||||
|
return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func CreateHttpServer(config *Config) *HttpServer {
|
func CreateHttpServer(config *Config) *HttpServer {
|
||||||
|
|
||||||
var httpserver *HttpServer
|
var httpserver *HttpServer
|
||||||
@@ -315,6 +339,10 @@ func CreateHttpServer(config *Config) *HttpServer {
|
|||||||
Handler: r,
|
Handler: r,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth := auth.NewBasicAuthenticator(config.AuthRealm, func(user string) {
|
||||||
|
return httpserver._database._db.Get("hosts/"+ user)
|
||||||
|
})
|
||||||
|
|
||||||
r.HandleFunc("/register", httpserver.registerHandler)
|
r.HandleFunc("/register", httpserver.registerHandler)
|
||||||
r.HandleFunc("/update", httpserver.updateHandler)
|
r.HandleFunc("/update", httpserver.updateHandler)
|
||||||
r.HandleFunc("/admin", httpserver.adminPage)
|
r.HandleFunc("/admin", httpserver.adminPage)
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ type Config struct {
|
|||||||
OAuth2ClientSecret string
|
OAuth2ClientSecret string
|
||||||
IssuerUrl string
|
IssuerUrl string
|
||||||
ZoneUrl string
|
ZoneUrl string
|
||||||
|
AuthRealm string
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
50
database.go
50
database.go
@@ -1,23 +1,19 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
"github.com/patrickmn/go-cache"
|
||||||
|
password "github.com/sethvargo/go-password/password"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
"math"
|
bcrypt "golang.org/x/crypto/bcrypt"
|
||||||
"math/big"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
@@ -57,11 +53,11 @@ func (d *Database) Authorize(host string, token_user string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(token) < sha512.Size {
|
if len(token) < sha256.Size {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(token_user) < sha512.Size {
|
if len(token_user) < sha256.Size {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,24 +70,21 @@ func (d *Database) Authorize(host string, token_user string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateToken() string {
|
func generateToken() (string, []byte, error) {
|
||||||
maxInt := big.NewInt(math.MaxInt64)
|
pw, err := password.Generate(64, 10, 10, false, false)
|
||||||
randInt, err := rand.Int(rand.Reader, maxInt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
h_plain := []byte(randInt.String() + time.Now().String())
|
|
||||||
|
|
||||||
h:= sha256.Sum256(h_plain)
|
hash, errHash := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost)
|
||||||
|
|
||||||
for i:=0;i<10000; i++ {
|
if errHash != nil {
|
||||||
h = sha256.Sum256(h[:])
|
return "", nil , errHash
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
base64.NewEncoder(base64.URLEncoding, &buf).Write(h[:])
|
return pw, hash, nil
|
||||||
return buf.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) IsBannedHost(host string) bool {
|
func (d *Database) IsBannedHost(host string) bool {
|
||||||
@@ -119,24 +112,27 @@ func (d *Database) IncrementBanHost(host string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (d *Database) CreateHost(host string) (string, error) {
|
func (d *Database) CreateHost(host string) (string, []byte, error) {
|
||||||
if d.ExistHost(host) {
|
if d.ExistHost(host) {
|
||||||
return "", errors.New("host already existent")
|
return "", nil, errors.New("host already existent")
|
||||||
}
|
}
|
||||||
|
|
||||||
if host == "" {
|
if host == "" {
|
||||||
return "", errors.New("given hostname is empty")
|
return "", nil, errors.New("given hostname is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := dns.IsDomainName(host + "." + d._zone); !ok {
|
if _, ok := dns.IsDomainName(host + "." + d._zone); !ok {
|
||||||
return "", errors.New("given hostname is invalid")
|
return "", nil, errors.New("given hostname is invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
token := generateToken()
|
pw, hash, errToken := generateToken()
|
||||||
d._db.Put([]byte("hosts/" + host), []byte(token), nil)
|
if errToken != nil {
|
||||||
|
return "", nil, errToken
|
||||||
|
}
|
||||||
|
|
||||||
return token, nil
|
d._db.Put([]byte("hosts/" + host), hash, nil)
|
||||||
|
return pw, hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
go.mod
3
go.mod
@@ -3,11 +3,14 @@ module ddnsService
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/abbot/go-http-auth v0.4.0
|
||||||
github.com/coreos/go-oidc/v3 v3.0.0
|
github.com/coreos/go-oidc/v3 v3.0.0
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/miekg/dns v1.1.35
|
github.com/miekg/dns v1.1.35
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
|
github.com/sethvargo/go-password v0.2.0
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1,4 +1,6 @@
|
|||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
|
||||||
|
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
|
||||||
github.com/coreos/go-oidc/v3 v3.0.0 h1:/mAA0XMgYJw2Uqm7WKGCsKnjitE/+A0FFbOmiRJm7LQ=
|
github.com/coreos/go-oidc/v3 v3.0.0 h1:/mAA0XMgYJw2Uqm7WKGCsKnjitE/+A0FFbOmiRJm7LQ=
|
||||||
github.com/coreos/go-oidc/v3 v3.0.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
|
github.com/coreos/go-oidc/v3 v3.0.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -27,6 +29,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
|
|||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI=
|
||||||
|
github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE=
|
||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|||||||
6
main.go
6
main.go
@@ -4,9 +4,9 @@ func main() {
|
|||||||
|
|
||||||
config := Config{
|
config := Config{
|
||||||
DataDir: "/var/lib/ddnsService",
|
DataDir: "/var/lib/ddnsService",
|
||||||
Addr: ":8999", OAuth2ClientID: "0oa472q93Zu227hXY5d6",
|
Addr: ":8999", OAuth2ClientID: "ddnsService",
|
||||||
OAuth2ClientSecret: "sj98SdfZxjkYxUd8NCbyhSuPX1D7kPARDRJ0kVUe",
|
OAuth2ClientSecret: "",
|
||||||
IssuerUrl: "https://dev-1614211.okta.com/oauth2/default",
|
IssuerUrl: "https://auth.voglfrei.net/auth/realms/master",
|
||||||
OAuth2RedirectUrl: "http://localhost:8999/admin",
|
OAuth2RedirectUrl: "http://localhost:8999/admin",
|
||||||
ZoneUrl: "hub.voglfrei.net"}
|
ZoneUrl: "hub.voglfrei.net"}
|
||||||
server := CreateHttpServer(&config)
|
server := CreateHttpServer(&config)
|
||||||
|
|||||||
24
oauth2.go
24
oauth2.go
@@ -13,15 +13,19 @@ import (
|
|||||||
type OidcClams struct {
|
type OidcClams struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Profile string `json:"profile"`
|
Profile string `json:"profile"`
|
||||||
|
Username string `json:"preferred_username"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type OAuth2 struct {
|
type OAuth2 struct {
|
||||||
|
LogoutUrl string `json:"end_session_endpoint"`
|
||||||
|
|
||||||
_ctx context.Context
|
_ctx context.Context
|
||||||
_oauth2Config *oauth2.Config
|
_oauth2Config *oauth2.Config
|
||||||
_oidcVerifier *oidc.IDTokenVerifier
|
_oidcVerifier *oidc.IDTokenVerifier
|
||||||
_oidcProvider *oidc.Provider
|
_oidcProvider *oidc.Provider
|
||||||
_nonces map[string]string
|
_nonces map[string]string
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OAuth2) GetClaims(w http.ResponseWriter, token *oidc.IDToken) (*OidcClams, error) {
|
func (o *OAuth2) GetClaims(w http.ResponseWriter, token *oidc.IDToken) (*OidcClams, error) {
|
||||||
@@ -42,6 +46,7 @@ func (o *OAuth2) checkOAuth(w http.ResponseWriter, r *http.Request, allowRedirec
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
log.Info("got id_token cookie")
|
log.Info("got id_token cookie")
|
||||||
token, err := o._oidcVerifier.Verify(o._ctx, cookie.Value)
|
token, err := o._oidcVerifier.Verify(o._ctx, cookie.Value)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
|
||||||
return nil, false
|
return nil, false
|
||||||
@@ -60,7 +65,6 @@ func (o *OAuth2) checkOAuth(w http.ResponseWriter, r *http.Request, allowRedirec
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
delete(o._nonces, state)
|
delete(o._nonces, state)
|
||||||
|
|
||||||
oauth2Token, err := o._oauth2Config.Exchange(o._ctx, code)
|
oauth2Token, err := o._oauth2Config.Exchange(o._ctx, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
|
||||||
@@ -72,7 +76,7 @@ func (o *OAuth2) checkOAuth(w http.ResponseWriter, r *http.Request, allowRedirec
|
|||||||
http.Error(w, "No id_token field in oauth2 token.", http.StatusInternalServerError)
|
http.Error(w, "No id_token field in oauth2 token.", http.StatusInternalServerError)
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
log.Info(rawIDToken)
|
|
||||||
token, err2 := o._oidcVerifier.Verify(o._ctx, rawIDToken)
|
token, err2 := o._oidcVerifier.Verify(o._ctx, rawIDToken)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
|
||||||
@@ -99,9 +103,10 @@ func (o *OAuth2) checkOAuth(w http.ResponseWriter, r *http.Request, allowRedirec
|
|||||||
} else {
|
} else {
|
||||||
//no auth code and no bearer -> redirect
|
//no auth code and no bearer -> redirect
|
||||||
if allowRedirect {
|
if allowRedirect {
|
||||||
nonce := generateToken()
|
pw, _ , _ := generateToken();
|
||||||
o._nonces[nonce] = nonce
|
o._nonces[pw] = pw
|
||||||
http.Redirect(w, r, o._oauth2Config.AuthCodeURL(nonce), http.StatusFound)
|
|
||||||
|
http.Redirect(w, r, o._oauth2Config.AuthCodeURL(pw), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false
|
return nil, false
|
||||||
@@ -123,7 +128,6 @@ func CreateOAuth2(config *Config) (*OAuth2, error) {
|
|||||||
|
|
||||||
// Configure an OpenID Connect aware OAuth2 client.
|
// Configure an OpenID Connect aware OAuth2 client.
|
||||||
verifier := provider.Verifier(oidcConfig)
|
verifier := provider.Verifier(oidcConfig)
|
||||||
|
|
||||||
oauthConfig := oauth2.Config{
|
oauthConfig := oauth2.Config{
|
||||||
ClientID: config.OAuth2ClientID,
|
ClientID: config.OAuth2ClientID,
|
||||||
ClientSecret: config.OAuth2ClientSecret,
|
ClientSecret: config.OAuth2ClientSecret,
|
||||||
@@ -132,11 +136,15 @@ func CreateOAuth2(config *Config) (*OAuth2, error) {
|
|||||||
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &OAuth2{
|
ret := OAuth2{
|
||||||
_ctx: ctx,
|
_ctx: ctx,
|
||||||
_oauth2Config: &oauthConfig,
|
_oauth2Config: &oauthConfig,
|
||||||
_oidcVerifier: verifier,
|
_oidcVerifier: verifier,
|
||||||
_oidcProvider: provider,
|
_oidcProvider: provider,
|
||||||
_nonces: make(map[string]string),
|
_nonces: make(map[string]string),
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
err = provider.Claims(&ret)
|
||||||
|
|
||||||
|
return &ret, nil
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,10 @@ import (
|
|||||||
|
|
||||||
type AdminPageParams struct {
|
type AdminPageParams struct {
|
||||||
Hosts map[string]string
|
Hosts map[string]string
|
||||||
Email string
|
Claims OidcClams
|
||||||
Profile string
|
|
||||||
Alerts []Alert
|
Alerts []Alert
|
||||||
IpAddresses map[string][]string
|
IpAddresses map[string][]string
|
||||||
|
LogoutUrl string
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,11 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<h5 class="card-title">Logged in as {{.Email}}</h5>
|
<h5 class="card-title">Logged in as {{.Claims.Username}} ({{.Claims.Email}})</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<a class="btn btn-outline-primary" href="#">Logout</a>
|
<a class="btn btn-outline-primary" href="{{.LogoutUrl}}">Logout</a>
|
||||||
</div>
|
</div>
|
||||||
<p class="card-text">{{.Profile}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user