mirror of
https://github.com/openziti/zrok.git
synced 2025-01-09 07:28:15 +01:00
fully roughed in auth models; none, basic (#12)
This commit is contained in:
parent
c6c1a470d3
commit
d87ec1257a
154
cmd/zrok/http.go
154
cmd/zrok/http.go
@ -1,17 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
ui "github.com/gizak/termui/v3"
|
||||
"github.com/gizak/termui/v3/widgets"
|
||||
"github.com/go-openapi/runtime"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
tb "github.com/nsf/termbox-go"
|
||||
"github.com/openziti-test-kitchen/zrok/http"
|
||||
"github.com/openziti-test-kitchen/zrok/model"
|
||||
"github.com/openziti-test-kitchen/zrok/rest_client_zrok"
|
||||
"github.com/openziti-test-kitchen/zrok/rest_client_zrok/tunnel"
|
||||
"github.com/openziti-test-kitchen/zrok/rest_model_zrok"
|
||||
"github.com/openziti-test-kitchen/zrok/zrokdir"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
@ -22,22 +20,34 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(httpCmd)
|
||||
rootCmd.AddCommand(newHttpCommand().cmd)
|
||||
}
|
||||
|
||||
var httpCmd = &cobra.Command{
|
||||
Use: "http <endpoint>",
|
||||
Short: "Start an http terminator",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: handleHttp,
|
||||
type httpCommand struct {
|
||||
basicAuth []string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func handleHttp(_ *cobra.Command, args []string) {
|
||||
if err := ui.Init(); err != nil {
|
||||
panic(err)
|
||||
func newHttpCommand() *httpCommand {
|
||||
cmd := &cobra.Command{
|
||||
Use: "http <endpoint>",
|
||||
Short: "Start an HTTP terminator",
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
defer ui.Close()
|
||||
tb.SetInputMode(tb.InputEsc)
|
||||
command := &httpCommand{cmd: cmd}
|
||||
cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (<username:password>,...")
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
|
||||
func (self *httpCommand) run(_ *cobra.Command, args []string) {
|
||||
/*
|
||||
if err := ui.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer ui.Close()
|
||||
tb.SetInputMode(tb.InputEsc)
|
||||
*/
|
||||
|
||||
idCfg, err := zrokdir.IdentityConfigFile()
|
||||
if err != nil {
|
||||
@ -62,6 +72,19 @@ func handleHttp(_ *cobra.Command, args []string) {
|
||||
req.Body = &rest_model_zrok.TunnelRequest{
|
||||
ZitiIdentityID: id,
|
||||
Endpoint: cfg.EndpointAddress,
|
||||
AuthScheme: string(model.None),
|
||||
}
|
||||
if len(self.basicAuth) > 0 {
|
||||
logrus.Infof("configuring basic auth")
|
||||
req.Body.AuthScheme = string(model.Basic)
|
||||
for _, pair := range self.basicAuth {
|
||||
tokens := strings.Split(pair, ":")
|
||||
if len(tokens) == 2 {
|
||||
req.Body.AuthUsers = append(req.Body.AuthUsers, &rest_model_zrok.AuthUser{Username: strings.TrimSpace(tokens[0]), Password: strings.TrimSpace(tokens[1])})
|
||||
} else {
|
||||
panic(errors.Errorf("invalid username:password pair '%v'", pair))
|
||||
}
|
||||
}
|
||||
}
|
||||
resp, err := zrok.Tunnel.Tunnel(req, auth)
|
||||
if err != nil {
|
||||
@ -88,64 +111,69 @@ func handleHttp(_ *cobra.Command, args []string) {
|
||||
}
|
||||
}()
|
||||
|
||||
ui.Clear()
|
||||
w, h := ui.TerminalDimensions()
|
||||
/*
|
||||
ui.Clear()
|
||||
w, h := ui.TerminalDimensions()
|
||||
|
||||
p := widgets.NewParagraph()
|
||||
p.Border = true
|
||||
p.Title = " access your zrok service "
|
||||
p.Text = fmt.Sprintf("%v%v", strings.Repeat(" ", (((w-12)-len(resp.Payload.ProxyEndpoint))/2)-1), resp.Payload.ProxyEndpoint)
|
||||
p.TextStyle = ui.Style{Fg: ui.ColorWhite}
|
||||
p.PaddingTop = 1
|
||||
p.SetRect(5, 5, w-10, 10)
|
||||
p := widgets.NewParagraph()
|
||||
p.Border = true
|
||||
p.Title = " access your zrok service "
|
||||
p.Text = fmt.Sprintf("%v%v", strings.Repeat(" ", (((w-12)-len(resp.Payload.ProxyEndpoint))/2)-1), resp.Payload.ProxyEndpoint)
|
||||
p.TextStyle = ui.Style{Fg: ui.ColorWhite}
|
||||
p.PaddingTop = 1
|
||||
p.SetRect(5, 5, w-10, 10)
|
||||
|
||||
lastRequests := float64(0)
|
||||
var requestData []float64
|
||||
spk := widgets.NewSparkline()
|
||||
spk.Title = " requests "
|
||||
spk.Data = requestData
|
||||
spk.LineColor = ui.ColorCyan
|
||||
lastRequests := float64(0)
|
||||
var requestData []float64
|
||||
spk := widgets.NewSparkline()
|
||||
spk.Title = " requests "
|
||||
spk.Data = requestData
|
||||
spk.LineColor = ui.ColorCyan
|
||||
|
||||
slg := widgets.NewSparklineGroup(spk)
|
||||
slg.SetRect(5, 11, w-10, h-5)
|
||||
slg := widgets.NewSparklineGroup(spk)
|
||||
slg.SetRect(5, 11, w-10, h-5)
|
||||
|
||||
ui.Render(p, slg)
|
||||
ui.Render(p, slg)
|
||||
|
||||
ticker := time.NewTicker(time.Second).C
|
||||
uiEvents := ui.PollEvents()
|
||||
for {
|
||||
select {
|
||||
case e := <-uiEvents:
|
||||
switch e.Type {
|
||||
case ui.ResizeEvent:
|
||||
ui.Clear()
|
||||
w, h = ui.TerminalDimensions()
|
||||
p.SetRect(5, 5, w-10, 10)
|
||||
slg.SetRect(5, 11, w-10, h-5)
|
||||
ui.Render(p, slg)
|
||||
ticker := time.NewTicker(time.Second).C
|
||||
uiEvents := ui.PollEvents()
|
||||
for {
|
||||
select {
|
||||
case e := <-uiEvents:
|
||||
switch e.Type {
|
||||
case ui.ResizeEvent:
|
||||
ui.Clear()
|
||||
w, h = ui.TerminalDimensions()
|
||||
p.SetRect(5, 5, w-10, 10)
|
||||
slg.SetRect(5, 11, w-10, h-5)
|
||||
ui.Render(p, slg)
|
||||
|
||||
case ui.KeyboardEvent:
|
||||
switch e.ID {
|
||||
case "q", "<C-c>":
|
||||
ui.Close()
|
||||
cleanupHttp(id, cfg, zrok, auth)
|
||||
os.Exit(0)
|
||||
case ui.KeyboardEvent:
|
||||
switch e.ID {
|
||||
case "q", "<C-c>":
|
||||
ui.Close()
|
||||
cleanupHttp(id, cfg, zrok, auth)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case <-ticker:
|
||||
currentRequests := float64(httpProxy.Requests())
|
||||
deltaRequests := currentRequests - lastRequests
|
||||
requestData = append(requestData, deltaRequests)
|
||||
lastRequests = currentRequests
|
||||
requestData = append(requestData, deltaRequests)
|
||||
for len(requestData) > w-17 {
|
||||
requestData = requestData[1:]
|
||||
case <-ticker:
|
||||
currentRequests := float64(httpProxy.Requests())
|
||||
deltaRequests := currentRequests - lastRequests
|
||||
requestData = append(requestData, deltaRequests)
|
||||
lastRequests = currentRequests
|
||||
requestData = append(requestData, deltaRequests)
|
||||
for len(requestData) > w-17 {
|
||||
requestData = requestData[1:]
|
||||
}
|
||||
spk.Title = fmt.Sprintf(" requests (%d) ", int(currentRequests))
|
||||
spk.Data = requestData
|
||||
ui.Render(p, slg)
|
||||
}
|
||||
spk.Title = fmt.Sprintf(" requests (%d) ", int(currentRequests))
|
||||
spk.Data = requestData
|
||||
ui.Render(p, slg)
|
||||
}
|
||||
*/
|
||||
for {
|
||||
time.Sleep(30 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"github.com/openziti-test-kitchen/zrok/model"
|
||||
"github.com/openziti-test-kitchen/zrok/util"
|
||||
@ -39,12 +38,7 @@ func Run(cfg *Config) error {
|
||||
return err
|
||||
}
|
||||
proxy.Transport = zTransport
|
||||
users := &model.BasicAuth{
|
||||
Users: []*model.AuthUser{
|
||||
{Username: "hello", Password: "world"},
|
||||
},
|
||||
}
|
||||
return http.ListenAndServe(cfg.Address, basicAuth(util.NewProxyHandler(proxy), users, "zrok", &resolver{}, zCtx))
|
||||
return http.ListenAndServe(cfg.Address, basicAuth(util.NewProxyHandler(proxy), "zrok", &resolver{}, zCtx))
|
||||
}
|
||||
|
||||
type resolver struct{}
|
||||
@ -165,38 +159,74 @@ func getRefreshedService(name string, ctx ziti.Context) (*edge.Service, bool) {
|
||||
return svc, found
|
||||
}
|
||||
|
||||
func basicAuth(handler http.Handler, users *model.BasicAuth, realm string, rslv ProxyServiceResolver, ctx ziti.Context) http.HandlerFunc {
|
||||
func basicAuth(handler http.Handler, realm string, rslv ProxyServiceResolver, ctx ziti.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
svcName := rslv.Service(r.Host)
|
||||
if svc, found := getRefreshedService(svcName, ctx); found {
|
||||
if cfg, found := svc.Configs[model.ZrokProxyConfig]; found {
|
||||
if scheme, found := cfg["auth_scheme"]; found {
|
||||
switch scheme {
|
||||
case model.None:
|
||||
case string(model.None):
|
||||
logrus.Infof("auth scheme none '%v'", svcName)
|
||||
handler.ServeHTTP(w, r)
|
||||
return
|
||||
|
||||
case model.Basic:
|
||||
case string(model.Basic):
|
||||
logrus.Infof("auth scheme basic '%v", svcName)
|
||||
inUser, inPass, ok := r.BasicAuth()
|
||||
if !ok {
|
||||
writeUnauthorizedResponse(w, realm)
|
||||
return
|
||||
}
|
||||
authed := false
|
||||
for _, v := range users.Users {
|
||||
if subtle.ConstantTimeCompare([]byte(inUser), []byte(v.Username)) == 1 && subtle.ConstantTimeCompare([]byte(inPass), []byte(v.Password)) == 1 {
|
||||
authed = true
|
||||
break
|
||||
if v, found := cfg["basic_auth"]; found {
|
||||
if basicAuth, ok := v.(map[string]interface{}); ok {
|
||||
if v, found := basicAuth["users"]; found {
|
||||
if arr, ok := v.([]interface{}); ok {
|
||||
for _, v := range arr {
|
||||
if um, ok := v.(map[string]interface{}); ok {
|
||||
username := ""
|
||||
if v, found := um["username"]; found {
|
||||
if un, ok := v.(string); ok {
|
||||
username = un
|
||||
}
|
||||
}
|
||||
password := ""
|
||||
if v, found := um["password"]; found {
|
||||
if pw, ok := v.(string); ok {
|
||||
password = pw
|
||||
}
|
||||
}
|
||||
if username == inUser && password == inPass {
|
||||
authed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !authed {
|
||||
writeUnauthorizedResponse(w, realm)
|
||||
return
|
||||
}
|
||||
handler.ServeHTTP(w, r)
|
||||
|
||||
default:
|
||||
logrus.Infof("invalid auth scheme '%v'", scheme)
|
||||
writeUnauthorizedResponse(w, realm)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logrus.Infof("no auth scheme for '%v'", svcName)
|
||||
}
|
||||
} else {
|
||||
logrus.Infof("no proxy config for '%v'", svcName)
|
||||
}
|
||||
} else {
|
||||
logrus.Infof("service '%v' not found", svcName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user