Skip to content

Commit

Permalink
FEAT: call dex directly instead of proxying argocd (devtron-labs#922)
Browse files Browse the repository at this point in the history
* local import working

* authenticator debug

* local tested

* local tested

* docker version upgrade

* argo dependency import

* removed filter

* login proxy correction

* user filter redirect

* commited dev ssl setting

* redirect url rewerite

* password login tested

* removed http only cookie

* admin login password verified

* local dev conf

* removed serve tls

* admin login acd deligate

* path prefix url compatible

* callback endpoint change

* auth redirect reverted

* refactor compiling

* commited wiregen

* auth related wiring extracted in seperate class

* authenticator upgrade

* middleware correcton

* authenticator upgrade
  • Loading branch information
nishant-d authored Dec 9, 2021
1 parent 5920bde commit b1e274c
Show file tree
Hide file tree
Showing 892 changed files with 98,477 additions and 43,112 deletions.
57 changes: 42 additions & 15 deletions App.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ package main

import (
"context"
"crypto/tls"
"fmt"
"github.com/argoproj/argo-cd/util/session"
"github.com/casbin/casbin"
authMiddleware "github.com/devtron-labs/authenticator/middleware"
"github.com/devtron-labs/devtron/api/router"
"github.com/devtron-labs/devtron/api/sse"
"github.com/devtron-labs/devtron/client/argocdServer"
Expand All @@ -38,30 +39,42 @@ import (
)

type App struct {
MuxRouter *router.MuxRouter
Logger *zap.SugaredLogger
SSE *sse.SSE
Enforcer *casbin.Enforcer
sessionManager *session.SessionManager
server *http.Server
db *pg.DB
pubsubClient *pubsub.PubSubClient
MuxRouter *router.MuxRouter
Logger *zap.SugaredLogger
SSE *sse.SSE
Enforcer *casbin.Enforcer
server *http.Server
db *pg.DB
pubsubClient *pubsub.PubSubClient
// used for local dev only
serveTls bool
sessionManager2 *authMiddleware.SessionManager
}

func NewApp(router *router.MuxRouter,
Logger *zap.SugaredLogger,
sse *sse.SSE,
manager *session.SessionManager,
versionService argocdServer.VersionService,
enforcer *casbin.Enforcer,
db *pg.DB,
pubsubClient *pubsub.PubSubClient) *App {
pubsubClient *pubsub.PubSubClient,
sessionManager2 *authMiddleware.SessionManager,
) *App {
//check argo connection
err := versionService.CheckVersion()
if err != nil {
log.Panic(err)
}
app := &App{MuxRouter: router, Logger: Logger, SSE: sse, Enforcer: enforcer, sessionManager: manager, db: db, pubsubClient: pubsubClient}
app := &App{
MuxRouter: router,
Logger: Logger,
SSE: sse,
Enforcer: enforcer,
db: db,
pubsubClient: pubsubClient,
serveTls: false,
sessionManager2: sessionManager2,
}
return app
}

Expand All @@ -83,11 +96,25 @@ func (app *App) Start() {
app.MuxRouter.Init()
//authEnforcer := casbin2.Create()

server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: user.Authorizer(app.Enforcer, app.sessionManager)(app.MuxRouter.Router)}

server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: authMiddleware.Authorizer(app.sessionManager2, user.WhitelistChecker)(app.MuxRouter.Router)}
app.MuxRouter.Router.Use(middleware.PrometheusMiddleware)
app.server = server
err := server.ListenAndServe()
var err error
if app.serveTls {
cert, err := tls.LoadX509KeyPair(
"localhost.crt",
"localhost.key",
)
if err != nil {
log.Fatal(err)
}
server.TLSConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
}
err = server.ListenAndServeTLS("", "")
} else {
err = server.ListenAndServe()
}
//err := http.ListenAndServe(fmt.Sprintf(":%d", port), auth.Authorizer(app.Enforcer, app.sessionManager)(app.MuxRouter.Router))
if err != nil {
app.Logger.Errorw("error in startup", "err", err)
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.15.10-alpine3.13 AS build-env
FROM golang:1.16.10-alpine3.13 AS build-env

RUN echo $GOPATH

Expand All @@ -9,7 +9,7 @@ WORKDIR /go/src/github.com/devtron-labs/devtron
ADD . /go/src/github.com/devtron-labs/devtron/
RUN GOOS=linux make

FROM alpine:3.13
FROM alpine:3.15.0
RUN apk add --no-cache ca-certificates
RUN apk update
RUN apk add git
Expand Down
4 changes: 3 additions & 1 deletion Wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ func InitializeApp() (*App, error) {
wire.Bind(new(restHandler.BulkUpdateRestHandler), new(*restHandler.BulkUpdateRestHandlerImpl)),

router.NewCoreAppRouterImpl,
wire.Bind(new(router.CoreAppRouter),new(*router.CoreAppRouterImpl)),
wire.Bind(new(router.CoreAppRouter), new(*router.CoreAppRouterImpl)),
restHandler.NewCoreAppRestHandlerImpl,
wire.Bind(new(restHandler.CoreAppRestHandler), new(*restHandler.CoreAppRestHandlerImpl)),

Expand Down Expand Up @@ -708,6 +708,8 @@ func InitializeApp() (*App, error) {
pipelineConfig.NewAppLabelRepositoryImpl,
wire.Bind(new(pipelineConfig.AppLabelRepository), new(*pipelineConfig.AppLabelRepositoryImpl)),
util2.NewGoJsonSchemaCustomFormatChecker,

AuthWireSet,
)
return &App{}, nil
}
29 changes: 23 additions & 6 deletions api/restHandler/UserAuthHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package restHandler
import (
"encoding/json"
"fmt"
"github.com/devtron-labs/authenticator/middleware"
"github.com/devtron-labs/devtron/api/restHandler/common"
"net/http"
"strings"
Expand Down Expand Up @@ -53,15 +54,31 @@ type UserAuthHandlerImpl struct {
natsClient *pubsub.PubSubClient
userService user.UserService
ssoLoginService sso.SSOLoginService
loginService *middleware.LoginService
}

const POLICY_UPDATE_TOPIC = "Policy.Update"

func NewUserAuthHandlerImpl(userAuthService user.UserAuthService, validator *validator.Validate,
logger *zap.SugaredLogger, enforcer rbac.Enforcer, natsClient *pubsub.PubSubClient, userService user.UserService,
ssoLoginService sso.SSOLoginService) *UserAuthHandlerImpl {
userAuthHandler := &UserAuthHandlerImpl{userAuthService: userAuthService, validator: validator, logger: logger,
enforcer: enforcer, natsClient: natsClient, userService: userService, ssoLoginService: ssoLoginService}
func NewUserAuthHandlerImpl(
userAuthService user.UserAuthService,
validator *validator.Validate,
logger *zap.SugaredLogger,
enforcer rbac.Enforcer,
natsClient *pubsub.PubSubClient,
userService user.UserService,
ssoLoginService sso.SSOLoginService,
loginService *middleware.LoginService,
) *UserAuthHandlerImpl {
userAuthHandler := &UserAuthHandlerImpl{
userAuthService: userAuthService,
validator: validator,
logger: logger,
enforcer: enforcer,
natsClient: natsClient,
userService: userService,
ssoLoginService: ssoLoginService,
loginService: loginService,
}

err := userAuthHandler.Subscribe()
if err != nil {
Expand All @@ -86,7 +103,7 @@ func (handler UserAuthHandlerImpl) LoginHandler(w http.ResponseWriter, r *http.R
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

//token, err := handler.loginService.CreateLoginSession(up.Username, up.Password)
token, err := handler.userAuthService.HandleLogin(up.Username, up.Password)
if err != nil {
common.WriteJsonResp(w, fmt.Errorf("invalid username or password"), nil, http.StatusForbidden)
Expand Down
62 changes: 24 additions & 38 deletions api/router/UserAuthRouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,16 @@
package router

import (
"fmt"
"github.com/argoproj/argo-cd/util/settings"
"github.com/devtron-labs/authenticator/client"
"github.com/devtron-labs/authenticator/oidc"
"github.com/devtron-labs/devtron/api/restHandler"
"github.com/devtron-labs/devtron/client/argocdServer"
"github.com/devtron-labs/devtron/pkg/dex"
"github.com/devtron-labs/devtron/pkg/user"
"github.com/gorilla/mux"
"go.uber.org/zap"
"net"
"net/http"
"time"
"strings"
)

type UserAuthRouter interface {
Expand All @@ -40,46 +39,34 @@ type UserAuthRouterImpl struct {
userAuthHandler restHandler.UserAuthHandler
cdProxy func(writer http.ResponseWriter, request *http.Request)
dexProxy func(writer http.ResponseWriter, request *http.Request)
clientApp *oidc.ClientApp
}

func NewUserAuthRouterImpl(logger *zap.SugaredLogger, userAuthHandler restHandler.UserAuthHandler, cdCfg *argocdServer.Config, dexCfg *dex.Config, settings *settings.ArgoCDSettings, userService user.UserService) *UserAuthRouterImpl {
func NewUserAuthRouterImpl(logger *zap.SugaredLogger, userAuthHandler restHandler.UserAuthHandler, settings *settings.ArgoCDSettings, userService user.UserService, dexConfig *client.DexConfig) (*UserAuthRouterImpl, error) {
tlsConfig := settings.TLSConfig()
if tlsConfig != nil {
tlsConfig.InsecureSkipVerify = true
}
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
}
dexClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
}
dexProxy := argocdServer.NewDexHTTPReverseProxy(fmt.Sprintf("%s:%s", dexCfg.Host, dexCfg.Port), dexClient.Transport)
cdProxy := argocdServer.NewCDHTTPReverseProxy(fmt.Sprintf("https://%s:%s", cdCfg.Host, cdCfg.Port), client.Transport, userService.GetUserByToken)
router := &UserAuthRouterImpl{
userAuthHandler: userAuthHandler,
cdProxy: cdProxy,
dexProxy: dexProxy,
logger: logger,
}
return router
logger.Infow("auth starting with dex conf", "conf", dexConfig)
oidcClient, dexProxy, err := client.GetOidcClient(dexConfig, userService.UserExists, router.RedirectUrlSanitiser)
if err != nil {
return nil, err
}
router.dexProxy = dexProxy
router.clientApp = oidcClient
return router, nil
}

// RedirectUrlSanitiser replaces initial "/orchestrator" from url
func (router UserAuthRouterImpl) RedirectUrlSanitiser(redirectUrl string) string {
if strings.Contains(redirectUrl, argocdServer.Dashboard) {
redirectUrl = strings.ReplaceAll(redirectUrl, argocdServer.Orchestrator, "")
}
return redirectUrl
}

func (router UserAuthRouterImpl) initUserAuthRouter(userAuthRouter *mux.Router) {
Expand All @@ -89,10 +76,9 @@ func (router UserAuthRouterImpl) initUserAuthRouter(userAuthRouter *mux.Router)
}).Methods("GET")

userAuthRouter.PathPrefix("/api/dex").HandlerFunc(router.dexProxy)
userAuthRouter.Path("/login").HandlerFunc(router.cdProxy)
userAuthRouter.Path("/auth/login").HandlerFunc(router.cdProxy)
userAuthRouter.PathPrefix("/auth/callback").HandlerFunc(router.cdProxy)

userAuthRouter.Path("/login").HandlerFunc(router.clientApp.HandleLogin)
userAuthRouter.Path("/auth/login").HandlerFunc(router.clientApp.HandleLogin)
userAuthRouter.Path("/auth/callback").HandlerFunc(router.clientApp.HandleCallback)
userAuthRouter.Path("/api/v1/session").HandlerFunc(router.userAuthHandler.LoginHandler)
userAuthRouter.Path("/refresh").HandlerFunc(router.userAuthHandler.RefreshTokenHandler)
// Policies mapping in orchestrator
Expand Down
17 changes: 17 additions & 0 deletions authWire.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
"github.com/devtron-labs/authenticator/client"
"github.com/devtron-labs/authenticator/middleware"
"github.com/google/wire"
)

// AuthWireSet: set of components used to initialise authentication with dex
var AuthWireSet = wire.NewSet(
wire.Value(client.LocalDevMode(false)),
client.NewK8sClient,
client.BuildDexConfig,
client.GetSettings,
middleware.NewSessionManager,
middleware.NewUserLogin,
)
31 changes: 11 additions & 20 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ require (
github.com/Azure/go-autorest/autorest/adal v0.9.13
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Pallinder/go-randomdata v1.2.0
github.com/ThreeDotsLabs/watermill v1.0.2 // indirect
github.com/argoproj/argo v2.4.1+incompatible
github.com/argoproj/argo-cd v1.2.3
github.com/argoproj/pkg v0.0.0-20190830164810-036726ef3c78 // indirect
Expand All @@ -17,9 +16,10 @@ require (
github.com/casbin/casbin v1.9.1
github.com/casbin/xorm-adapter v1.0.1-0.20190716004226-a317737a1007
github.com/colinmarc/hdfs v1.1.4-0.20180805212432-9746310a4d31 // indirect
github.com/coreos/go-oidc v2.1.0+incompatible
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
github.com/davecgh/go-spew v1.1.1
github.com/devtron-labs/authenticator v0.4.18
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e // indirect
github.com/emicklei/go-restful v2.11.0+incompatible // indirect
Expand All @@ -36,16 +36,15 @@ require (
github.com/gobuffalo/envy v1.7.1 // indirect
github.com/gobuffalo/packr v1.30.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.1
github.com/golang-jwt/jwt/v4 v4.0.0
github.com/gogo/protobuf v1.3.2
github.com/golang-jwt/jwt/v4 v4.1.0
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.3.2
github.com/google/go-cmp v0.3.0
github.com/golang/protobuf v1.4.2
github.com/google/go-cmp v0.5.1
github.com/google/go-github v17.0.0+incompatible
github.com/google/uuid v1.1.5 // indirect
github.com/google/wire v0.3.0
github.com/googleapis/gnostic v0.3.1 // indirect
github.com/gorilla/mux v1.7.3
github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.1.0
github.com/gorilla/sessions v1.2.0
github.com/gorilla/websocket v1.4.1 // indirect
Expand All @@ -56,7 +55,6 @@ require (
github.com/hashicorp/go-uuid v1.0.1 // indirect
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/igm/sockjs-go v3.0.0+incompatible // indirect
github.com/imdario/mergo v0.3.8 // indirect
github.com/jcmturner/gofork v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/json-iterator/go v1.1.8 // indirect
Expand All @@ -75,9 +73,7 @@ require (
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1
github.com/posthog/posthog-go v0.0.0-20210610161230-cd4408afb35a
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/prometheus/client_golang v1.1.0
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect
github.com/prometheus/common v0.7.0 // indirect
github.com/prometheus/procfs v0.0.5 // indirect
github.com/robfig/cron/v3 v3.0.1
Expand All @@ -93,26 +89,21 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0
go.uber.org/multierr v1.2.0 // indirect
go.uber.org/zap v1.10.0
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
google.golang.org/appengine v1.6.5
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03 // indirect
google.golang.org/grpc v1.24.0
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
google.golang.org/grpc v1.31.0
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/go-playground/validator.v9 v9.30.0
gopkg.in/igm/sockjs-go.v3 v3.0.0
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/jcmturner/goidentity.v2 v2.0.0 // indirect
gopkg.in/square/go-jose.v2 v2.3.1 // indirect
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20191004102349-159aefb8556b
k8s.io/apimachinery v0.0.0-20190816221834-a9f1d8a9c101
k8s.io/client-go v11.0.1-0.20190820062731-7e43eff7c80a+incompatible
k8s.io/helm v2.12.3+incompatible
k8s.io/klog v1.0.0 // indirect
k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d // indirect
k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 // indirect
mellium.im/sasl v0.2.1 // indirect
xorm.io/core v0.7.2 // indirect
)

replace github.com/devtron-labs/authenticator => github.com/nishant-d/authenticator v0.4.18
Loading

0 comments on commit b1e274c

Please sign in to comment.