diff --git a/Dockerfile b/Dockerfile index 75d8dddd..c87f8a3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,9 +3,9 @@ ###################################### FROM node:18 as npm_builder WORKDIR /go/src/github.com/Allen-Career-Institute/flagr -ARG ENVIRONMENT=production +ARG ENVIRONMENT=local ENV ENVIRONMENT=${ENVIRONMENT} -ADD . . +COPY . . ARG FLAGR_UI_POSSIBLE_ENTITY_TYPES=null ENV VUE_APP_FLAGR_UI_POSSIBLE_ENTITY_TYPES ${FLAGR_UI_POSSIBLE_ENTITY_TYPES} RUN make build_ui @@ -16,8 +16,8 @@ RUN make build_ui FROM golang:1.21-alpine as go_builder WORKDIR /go/src/github.com/Allen-Career-Institute/flagr -RUN apk add --no-cache git make build-base -ADD . . +RUN apk add --no-cache build-base git make +COPY . . RUN make build FROM alpine @@ -25,7 +25,9 @@ FROM alpine COPY --from=go_builder /go/src/github.com/Allen-Career-Institute/flagr/flagr . ENV HOST=0.0.0.0 -ENV PORT=3000 +# ENV PORT=3000 (for local testing) +ENV PORT=18000 + ENV FLAGR_DB_DBDRIVER=sqlite3 ENV FLAGR_DB_DBCONNECTIONSTR=/data/demo_sqlite3.db ENV FLAGR_RECORDER_ENABLED=false @@ -33,13 +35,13 @@ ENV FLAGR_RECORDER_ENABLED=false # JWT Environment Variables ENV FLAGR_JWT_AUTH_ENABLED=true ENV FLAGR_JWT_AUTH_DEBUG=true -ENV FLAGR_JWT_AUTH_WHITELIST_PATHS="/api/v1/health,/api/v1/evaluation,/login,/callback,/static,/favicon.ico,/flags" +ENV FLAGR_JWT_AUTH_WHITELIST_PATHS="/api/v1/health,/api/v1/evaluation,/login,/callback,/static,/favicon.ico" ENV FLAGR_JWT_AUTH_EXACT_WHITELIST_PATHS=",/,/login,/callback" ENV FLAGR_JWT_AUTH_COOKIE_TOKEN_NAME="access_token" -#ENV FLAGR_JWT_AUTH_SECRET="" +# ENV FLAGR_JWT_AUTH_SECRET="secret" ENV FLAGR_JWT_AUTH_NO_TOKEN_STATUS_CODE=307 -ENV FLAGR_JWT_AUTH_NO_TOKEN_REDIRECT_URL="http://localhost:3000/login" -ENV FLAGR_JWT_AUTH_USER_PROPERTY=flagr_user +# ENV FLAGR_JWT_AUTH_NO_TOKEN_REDIRECT_URL="http://localhost:3000/login" (for local testing) +ENV FLAGR_JWT_AUTH_NO_TOKEN_REDIRECT_URL="http://localhost:18000/login" ENV FLAGR_JWT_AUTH_USER_CLAIM=uid ENV FLAGR_JWT_AUTH_SIGNING_METHOD=HS256 @@ -48,8 +50,9 @@ COPY --from=npm_builder /go/src/github.com/Allen-Career-Institute/flagr/browser/ RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser -ADD --chown=appuser:appgroup ./buildscripts/demo_sqlite3.db /data/demo_sqlite3.db +COPY --chown=appuser:appgroup ./buildscripts/demo_sqlite3.db /data/demo_sqlite3.db -EXPOSE 3000 +# EXPOSE 3000 (for local testing) +EXPOSE 18000 CMD "./flagr" diff --git a/Makefile b/Makefile index 31d4b32b..33491a00 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ ifeq ($(ENVIRONMENT),dev) BUILD_CMD = build:dev else ifeq ($(ENVIRONMENT),stage) BUILD_CMD = build:stage +else ifeq ($(ENVIRONMENT),local) + BUILD_CMD = build:local else BUILD_CMD = build endif diff --git a/browser/flagr-ui/package.json b/browser/flagr-ui/package.json index 7e94d34b..f9d9ea67 100644 --- a/browser/flagr-ui/package.json +++ b/browser/flagr-ui/package.json @@ -7,6 +7,7 @@ "build": "vue-cli-service build", "build:stage": "vue-cli-service build --mode stage", "build:dev": "vue-cli-service build --mode dev", + "build:local": "vue-cli-service build --mode local", "lint": "vue-cli-service lint", "watch": "vue-cli-service build --watch" }, diff --git a/pkg/config/jwtmiddleware/jwt_middleware.go b/pkg/config/jwtmiddleware/jwt_middleware.go index 3c881a2f..3a08f8f7 100644 --- a/pkg/config/jwtmiddleware/jwt_middleware.go +++ b/pkg/config/jwtmiddleware/jwt_middleware.go @@ -21,8 +21,8 @@ type errorHandler func(w http.ResponseWriter, r *http.Request, err string) // be treated as an error. An empty string should be returned in that case. type TokenExtractor func(r *http.Request) (string, error) -// Define a custom type for the key -type contextKey string +// ContextKey Define a custom type for the key +type ContextKey string // Options is a struct for specifying configuration options for the middleware. type Options struct { @@ -233,7 +233,7 @@ func (m *JWTMiddleware) CheckJWT(w http.ResponseWriter, r *http.Request) error { // If we get here, everything worked and we can set the // user property in context. - newRequest := r.WithContext(context.WithValue(r.Context(), contextKey(m.Options.UserProperty), parsedToken)) + newRequest := r.WithContext(context.WithValue(r.Context(), ContextKey(m.Options.UserProperty), parsedToken)) // Update the current request with the new context information. *r = *newRequest return nil diff --git a/pkg/config/jwtmiddleware/jwt_middleware_test.go b/pkg/config/jwtmiddleware/jwt_middleware_test.go index a0bb01d0..a71092a7 100644 --- a/pkg/config/jwtmiddleware/jwt_middleware_test.go +++ b/pkg/config/jwtmiddleware/jwt_middleware_test.go @@ -194,7 +194,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { // in the token as json -> {"text":"bar"} func protectedHandler(w http.ResponseWriter, r *http.Request) { // retrieve the token from the context - u := r.Context().Value(contextKey(userPropertyName)) + u := r.Context().Value(ContextKey(userPropertyName)) if u == nil { http.Error(w, "Unauthorized: no token present", http.StatusUnauthorized) return diff --git a/pkg/config/middleware.go b/pkg/config/middleware.go index d8391559..4971b928 100644 --- a/pkg/config/middleware.go +++ b/pkg/config/middleware.go @@ -119,6 +119,12 @@ func createCORSMiddleware() negroni.Handler { // applyStaticFileMiddleware handles static files and Vue.js routing func applyStaticFileMiddleware(n *negroni.Negroni) { + n.Use(&negroni.Static{ + Dir: http.Dir("./browser/flagr-ui/dist/"), + Prefix: Config.WebPrefix, + IndexFile: "index.html", + }) + n.UseFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { if strings.Contains(r.URL.Path, "/api/") { next(w, r) diff --git a/pkg/handler/eval.go b/pkg/handler/eval.go index 15367c75..5688d810 100644 --- a/pkg/handler/eval.go +++ b/pkg/handler/eval.go @@ -176,10 +176,11 @@ var EvalFlagWithContext = func(flag *entity.Flag, evalContext models.EvalContext } logs := []*models.SegmentDebugLog{} - var vID int64 - var sID int64 - - var evalNextSegment bool + var ( + vID int64 + sID int64 + evalNextSegment bool + ) for _, segment := range flag.Segments { sID = int64(segment.ID) @@ -200,10 +201,12 @@ var EvalFlagWithContext = func(flag *entity.Flag, evalContext models.EvalContext } evalResult := BlankResult(flag, evalContext, "") evalResult.EvalDebugLog.SegmentDebugLogs = logs + if !evalNextSegment { evalResult.SegmentID = sID } evalResult.VariantID = vID + v := flag.FlagEvaluation.VariantsMap[util.SafeUint(vID)] if v != nil { evalResult.VariantAttachment = v.Attachment diff --git a/pkg/handler/subject.go b/pkg/handler/subject.go index a2c7eae7..bafa604d 100644 --- a/pkg/handler/subject.go +++ b/pkg/handler/subject.go @@ -3,6 +3,8 @@ package handler import ( "net/http" + "github.com/Allen-Career-Institute/flagr/pkg/config/jwtmiddleware" + "github.com/Allen-Career-Institute/flagr/pkg/config" "github.com/Allen-Career-Institute/flagr/pkg/util" @@ -15,7 +17,7 @@ func getSubjectFromRequest(r *http.Request) string { } if config.Config.JWTAuthEnabled { - token, ok := r.Context().Value(config.Config.JWTAuthUserProperty).(*jwt.Token) + token, ok := r.Context().Value(jwtmiddleware.ContextKey(config.Config.JWTAuthUserProperty)).(*jwt.Token) if !ok { return "" }