From 383dd631391c6ec6617fd1ef4dc147581a724428 Mon Sep 17 00:00:00 2001 From: James Batt Date: Wed, 19 Feb 2020 23:38:46 +1100 Subject: [PATCH] wip --- internal/auth/authconfig/authconfig.go | 4 +- internal/auth/authconfig/basic.go | 8 ++- internal/auth/authconfig/gitlab.go | 4 +- internal/auth/authconfig/oidc.go | 14 ++++- internal/auth/authruntime/runtime.go | 2 + internal/auth/authtemplates/login.go | 48 +++++++---------- internal/auth/router.go | 26 ++++++++-- website/src/sdk/devices_pb.ts | 71 +++++++++----------------- website/src/sdk/server_pb.ts | 24 +++------ 9 files changed, 93 insertions(+), 108 deletions(-) diff --git a/internal/auth/authconfig/authconfig.go b/internal/auth/authconfig/authconfig.go index 244575ba..3c506a30 100644 --- a/internal/auth/authconfig/authconfig.go +++ b/internal/auth/authconfig/authconfig.go @@ -1,6 +1,8 @@ package authconfig -import "github.com/place1/wireguard-access-server/internal/auth/authruntime" +import ( + "github.com/place1/wireguard-access-server/internal/auth/authruntime" +) type AuthConfig struct { OIDC *OIDCConfig `yaml:"oidc"` diff --git a/internal/auth/authconfig/basic.go b/internal/auth/authconfig/basic.go index 84bd7647..083819ba 100644 --- a/internal/auth/authconfig/basic.go +++ b/internal/auth/authconfig/basic.go @@ -5,7 +5,6 @@ import ( "net/http" "strings" - "github.com/gorilla/mux" "github.com/place1/wireguard-access-server/internal/auth/authruntime" "github.com/place1/wireguard-access-server/internal/auth/authsession" "github.com/tg123/go-htpasswd" @@ -21,16 +20,15 @@ type BasicAuthConfig struct { func (c *BasicAuthConfig) Provider() *authruntime.Provider { return &authruntime.Provider{ - RegisterRoutes: func(router *mux.Router, runtime *authruntime.ProviderRuntime) error { - router.HandleFunc("/login", basicAuthLogin(c, runtime)) - return nil + Type: "Basic", + Invoke: func(w http.ResponseWriter, r *http.Request, runtime *authruntime.ProviderRuntime) { + basicAuthLogin(c, runtime)(w, r) }, } } func basicAuthLogin(c *BasicAuthConfig, runtime *authruntime.ProviderRuntime) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - u, p, ok := r.BasicAuth() if !ok { w.Header().Set("WWW-Authenticate", `Basic realm="site"`) diff --git a/internal/auth/authconfig/gitlab.go b/internal/auth/authconfig/gitlab.go index b17ba273..847e5c73 100644 --- a/internal/auth/authconfig/gitlab.go +++ b/internal/auth/authconfig/gitlab.go @@ -19,5 +19,7 @@ func (c *GitlabConfig) Provider() *authruntime.Provider { RedirectURL: c.RedirectURL, Scopes: []string{"openid"}, } - return o.Provider() + p := o.Provider() + p.Type = "Gitlab" + return p } diff --git a/internal/auth/authconfig/oidc.go b/internal/auth/authconfig/oidc.go index f5c76085..53ea5969 100644 --- a/internal/auth/authconfig/oidc.go +++ b/internal/auth/authconfig/oidc.go @@ -3,10 +3,12 @@ package authconfig import ( "context" "net/http" + "net/url" "time" "github.com/coreos/go-oidc" "github.com/gorilla/mux" + "github.com/pkg/errors" "github.com/place1/wireguard-access-server/internal/auth/authruntime" "github.com/place1/wireguard-access-server/internal/auth/authsession" "github.com/place1/wireguard-access-server/internal/auth/authutil" @@ -43,10 +45,18 @@ func (c *OIDCConfig) Provider() *authruntime.Provider { Endpoint: provider.Endpoint(), } + redirectURL, err := url.Parse(c.RedirectURL) + if err != nil { + panic(errors.Wrapf(err, "redirect url is not valid: %s", c.RedirectURL)) + } + return &authruntime.Provider{ + Type: "OIDC", + Invoke: func(w http.ResponseWriter, r *http.Request, runtime *authruntime.ProviderRuntime) { + loginHandler(runtime, oauthConfig)(w, r) + }, RegisterRoutes: func(router *mux.Router, runtime *authruntime.ProviderRuntime) error { - router.HandleFunc("/login", loginHandler(runtime, oauthConfig)) - router.HandleFunc("/callback", callbackHandler(runtime, oauthConfig, provider)) + router.HandleFunc(redirectURL.Path, callbackHandler(runtime, oauthConfig, provider)) return nil }, } diff --git a/internal/auth/authruntime/runtime.go b/internal/auth/authruntime/runtime.go index 582c62bf..779faeb4 100644 --- a/internal/auth/authruntime/runtime.go +++ b/internal/auth/authruntime/runtime.go @@ -9,6 +9,8 @@ import ( ) type Provider struct { + Type string + Invoke func(http.ResponseWriter, *http.Request, *ProviderRuntime) RegisterRoutes func(*mux.Router, *ProviderRuntime) error } diff --git a/internal/auth/authtemplates/login.go b/internal/auth/authtemplates/login.go index 18ad5452..43e341db 100644 --- a/internal/auth/authtemplates/login.go +++ b/internal/auth/authtemplates/login.go @@ -4,11 +4,11 @@ import ( "html/template" "io" - "github.com/place1/wireguard-access-server/internal/auth/authconfig" + "github.com/place1/wireguard-access-server/internal/auth/authruntime" ) type LoginPage struct { - Config *authconfig.AuthConfig + Providers []*authruntime.Provider } func RenderLoginPage(w io.Writer, data LoginPage) error { @@ -34,11 +34,11 @@ const loginPage string = ` .form { position: absolute; - top: 40%; + top: 50%; left: 50%; + transform: translate(-50%, -50%); background-color: #fff; width: 285px; - margin: -140px 0 0 -182px; padding: 40px; box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); } @@ -59,7 +59,6 @@ const loginPage string = ` border: 1px solid #ccc; color: #ccc; box-sizing: border-box; - transition: 0.2s linear; } .form * { @@ -105,34 +104,25 @@ const loginPage string = ` background-color: #4d4d4d; border-radius: 50%; } - - .error, .valid{display:none;} - - -
+

Login To Your Account

-

Valid. Please wait a moment.

-

Error. Please enter correct Username & password.

-
- - {{if .Config.Basic}} - - - - {{end}} - -
- - {{if .Config.OIDC}} - - {{end}} - - {{if .Config.Gitlab}} - - {{end}} + {{range $i, $p := .Providers}} + + + + {{end}} + + +
` diff --git a/internal/auth/router.go b/internal/auth/router.go index 3f034fd4..41cca08c 100644 --- a/internal/auth/router.go +++ b/internal/auth/router.go @@ -3,6 +3,7 @@ package auth import ( "fmt" "net/http" + "strconv" "github.com/place1/wireguard-access-server/internal/auth/authconfig" "github.com/place1/wireguard-access-server/internal/auth/authruntime" @@ -27,16 +28,31 @@ func (m *AuthMiddleware) Wrap(next http.Handler) http.Handler { runtime := authruntime.NewProviderRuntime(sessions.NewCookieStore([]byte(authutil.RandomString(32)))) router := mux.NewRouter() - for _, p := range m.config.Providers() { - p.RegisterRoutes(router, runtime) + providers := m.config.Providers() + + for _, p := range providers { + if p.RegisterRoutes != nil { + p.RegisterRoutes(router, runtime) + } } - router.PathPrefix("/signin").Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + router.HandleFunc("/signin", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprint(w, authtemplates.RenderLoginPage(w, authtemplates.LoginPage{ - Config: m.config, + Providers: providers, })) - })) + }) + + router.HandleFunc("/signin/{index}", func(w http.ResponseWriter, r *http.Request) { + index, err := strconv.Atoi(mux.Vars(r)["index"]) + if err != nil || (index < 0 || index >= len(providers)) { + fmt.Fprintf(w, "unknown provider") + w.WriteHeader(http.StatusBadRequest) + return + } + provider := providers[index] + provider.Invoke(w, r, runtime) + }) router.PathPrefix("/").Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if s, err := runtime.GetSession(r); err == nil { diff --git a/website/src/sdk/devices_pb.ts b/website/src/sdk/devices_pb.ts index 71524cc2..51811d3e 100644 --- a/website/src/sdk/devices_pb.ts +++ b/website/src/sdk/devices_pb.ts @@ -98,7 +98,6 @@ export class Devices { - export declare namespace Device { export type AsObject = { name: string, @@ -111,13 +110,9 @@ export declare namespace Device { export class Device extends jspb.Message { - private static repeatedFields_ = [ - - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, Device.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -169,12 +164,12 @@ export class Device extends jspb.Message { toObject(): Device.AsObject { let f: any; - return {name: this.getName(), + return { + name: this.getName(), owner: this.getOwner(), publicKey: this.getPublicKey(), address: this.getAddress(), createdAt: (f = this.getCreatedAt()) && f.toObject(), - }; } @@ -243,8 +238,7 @@ export class Device extends jspb.Message { return message; } -} -export declare namespace AddDeviceReq { +}export declare namespace AddDeviceReq { export type AsObject = { name: string, publicKey: string, @@ -253,13 +247,9 @@ export declare namespace AddDeviceReq { export class AddDeviceReq extends jspb.Message { - private static repeatedFields_ = [ - - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, AddDeviceReq.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -287,9 +277,9 @@ export class AddDeviceReq extends jspb.Message { toObject(): AddDeviceReq.AsObject { let f: any; - return {name: this.getName(), + return { + name: this.getName(), publicKey: this.getPublicKey(), - }; } @@ -333,21 +323,16 @@ export class AddDeviceReq extends jspb.Message { return message; } -} -export declare namespace ListDevicesReq { +}export declare namespace ListDevicesReq { export type AsObject = { } } export class ListDevicesReq extends jspb.Message { - private static repeatedFields_ = [ - - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, ListDevicesReq.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -387,22 +372,17 @@ export class ListDevicesReq extends jspb.Message { return message; } -} -export declare namespace ListDevicesRes { +}export declare namespace ListDevicesRes { export type AsObject = { - items: Array, + items?: Array, } } export class ListDevicesRes extends jspb.Message { - private static repeatedFields_ = [ - 1, - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, ListDevicesRes.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -410,7 +390,7 @@ export class ListDevicesRes extends jspb.Message { return jspb.Message.getRepeatedWrapperField(this, Device, 1); } - setItems(value: Array): void { + setItems(value?: Array): void { (jspb.Message as any).setRepeatedWrapperField(this, 1, value); } @@ -427,7 +407,7 @@ export class ListDevicesRes extends jspb.Message { toObject(): ListDevicesRes.AsObject { let f: any; return { - items: this.getItems().map((item) => item.toObject()), + items: (f = this.getItems()) && f.toObject(), }; } @@ -464,8 +444,7 @@ export class ListDevicesRes extends jspb.Message { return message; } -} -export declare namespace DeleteDeviceReq { +}export declare namespace DeleteDeviceReq { export type AsObject = { name: string, } @@ -473,13 +452,9 @@ export declare namespace DeleteDeviceReq { export class DeleteDeviceReq extends jspb.Message { - private static repeatedFields_ = [ - - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, DeleteDeviceReq.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -499,8 +474,8 @@ export class DeleteDeviceReq extends jspb.Message { toObject(): DeleteDeviceReq.AsObject { let f: any; - return {name: this.getName(), - + return { + name: this.getName(), }; } diff --git a/website/src/sdk/server_pb.ts b/website/src/sdk/server_pb.ts index 321f835b..0467a37c 100644 --- a/website/src/sdk/server_pb.ts +++ b/website/src/sdk/server_pb.ts @@ -47,7 +47,6 @@ export class Server { - export declare namespace InfoReq { export type AsObject = { } @@ -55,13 +54,9 @@ export declare namespace InfoReq { export class InfoReq extends jspb.Message { - private static repeatedFields_ = [ - - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, InfoReq.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -101,8 +96,7 @@ export class InfoReq extends jspb.Message { return message; } -} -export declare namespace InfoRes { +}export declare namespace InfoRes { export type AsObject = { publicKey: string, host?: googleProtobufWrappers.StringValue.AsObject, @@ -113,13 +107,9 @@ export declare namespace InfoRes { export class InfoRes extends jspb.Message { - private static repeatedFields_ = [ - - ]; - - constructor(data?: jspb.Message.MessageArray) { + constructor() { super(); - jspb.Message.initialize(this, data || [], 0, -1, InfoRes.repeatedFields_, null); + jspb.Message.initialize(this, [], 0, -1, [], null); } @@ -163,11 +153,11 @@ export class InfoRes extends jspb.Message { toObject(): InfoRes.AsObject { let f: any; - return {publicKey: this.getPublicKey(), + return { + publicKey: this.getPublicKey(), host: (f = this.getHost()) && f.toObject(), port: this.getPort(), hostVpnIp: this.getHostVpnIp(), - }; }