Skip to content

Commit

Permalink
Embed UI & Login Redirects (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
KCarretto authored and hulto committed Sep 30, 2023
1 parent 85c5942 commit 39be32f
Show file tree
Hide file tree
Showing 21 changed files with 224 additions and 36 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ cmd/implants/Cargo.lock

# Build artifacts
dist/**
build/**

# Binaries for programs and plugins
*.exe
Expand Down
73 changes: 38 additions & 35 deletions tavern/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import (
"net/http"
"os"

"entgo.io/contrib/entgql"
"github.com/kcarretto/realm/tavern/graphql"
"github.com/kcarretto/realm/tavern/tomes"

"entgo.io/contrib/entgql"
gqlgraphql "github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/kcarretto/realm/tavern/auth"
"github.com/kcarretto/realm/tavern/ent"
"github.com/kcarretto/realm/tavern/ent/migrate"
"github.com/kcarretto/realm/tavern/graphql"
"github.com/kcarretto/realm/tavern/internal/cdn"
"github.com/kcarretto/realm/tavern/internal/www"
"github.com/urfave/cli"
)

Expand Down Expand Up @@ -105,45 +106,16 @@ func NewServer(ctx context.Context, options ...func(*Config)) (*Server, error) {
createTestData(ctx, client)
}

// Create GraphQL Handler
srv := handler.NewDefaultServer(graphql.NewSchema(client))
srv.Use(entgql.Transactioner{TxOpener: client})

// GraphQL Logging
gqlLogger := log.New(os.Stderr, "[GraphQL] ", log.Flags())
srv.AroundOperations(func(ctx context.Context, next gqlgraphql.OperationHandler) gqlgraphql.ResponseHandler {
oc := gqlgraphql.GetOperationContext(ctx)
reqVars, err := json.Marshal(oc.Variables)
if err != nil {
gqlLogger.Printf("[ERROR] failed to marshal variables to JSON: %v", err)
return next(ctx)
}

authName := "unknown"
id := auth.IdentityFromContext(ctx)
if id != nil {
authName = id.String()
}

gqlLogger.Printf("%s (%s): %s", oc.OperationName, authName, string(reqVars))
return next(ctx)
})

// Setup HTTP Handler
// Setup HTTP Handlers
router := http.NewServeMux()
router.Handle("/status", newStatusHandler())
router.Handle("/",
playground.Handler("Tavern", "/graphql"),
)
router.Handle("/graphql", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
srv.ServeHTTP(w, req)
}))
router.Handle("/oauth/login", auth.NewOAuthLoginHandler(cfg.oauth, privKey))
router.Handle("/oauth/authorize", auth.NewOAuthAuthorizationHandler(cfg.oauth, pubKey, client, "https://www.googleapis.com/oauth2/v3/userinfo"))
router.Handle("/graphql", newGraphQLHandler(client))
router.Handle("/cdn/", cdn.NewDownloadHandler(client))
router.Handle("/cdn/upload", cdn.NewUploadHandler(client))
router.Handle("/", auth.WithLoginRedirect("/oauth/login", www.NewAppHandler()))
router.Handle("/playground", auth.WithLoginRedirect("/oauth/login", playground.Handler("Tavern", "/graphql")))

// Log Middleware
httpLogger := log.New(os.Stderr, "[HTTP] ", log.Flags())
Expand Down Expand Up @@ -181,3 +153,34 @@ func NewServer(ctx context.Context, options ...func(*Config)) (*Server, error) {
client: client,
}, nil
}

func newGraphQLHandler(client *ent.Client) http.Handler {
srv := handler.NewDefaultServer(graphql.NewSchema(client))
srv.Use(entgql.Transactioner{TxOpener: client})

// GraphQL Logging
gqlLogger := log.New(os.Stderr, "[GraphQL] ", log.Flags())
srv.AroundOperations(func(ctx context.Context, next gqlgraphql.OperationHandler) gqlgraphql.ResponseHandler {
oc := gqlgraphql.GetOperationContext(ctx)
reqVars, err := json.Marshal(oc.Variables)
if err != nil {
gqlLogger.Printf("[ERROR] failed to marshal variables to JSON: %v", err)
return next(ctx)
}

authName := "unknown"
id := auth.IdentityFromContext(ctx)
if id != nil {
authName = id.String()
}

gqlLogger.Printf("%s (%s): %s", oc.OperationName, authName, string(reqVars))
return next(ctx)
})

return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
srv.ServeHTTP(w, req)
})
}
12 changes: 12 additions & 0 deletions tavern/auth/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,15 @@ func Middleware(handler http.Handler, graph *ent.Client) http.HandlerFunc {
handler.ServeHTTP(w, r)
})
}

// WithLoginRedirect will redirect requests for the provided handler to the provided redirect URL if the request is unauthenticated.
func WithLoginRedirect(redirect string, handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if !IsAuthenticatedContext(req.Context()) {
http.Redirect(w, req, redirect, http.StatusFound)
return
}
handler.ServeHTTP(w, req)
})

}
4 changes: 4 additions & 0 deletions tavern/internal/www/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ _If this is your first time contributing WWW changes in this dev environment, re
2. Run `go run ./tavern` to start the teamserver (for the GraphQL API) run in the project root
* Note: to run the teamserver with test data (useful for UI development), run `ENABLE_TEST_DATA=1 go run ./tavern` instead
3. In a separate terminal, navigate to the [UI Root /cmd/tavern/internal/www](https://github.com/KCarretto/realm/tree/main/cmd/tavern/internal/www) and run `npm start`

## Building the Application

When you're ready to include changes to the UI in the tavern binary, you'll need to run `npm build` to update files in the `build/` directory. These files will automatically be bundled into new compliations of the tavern binary.
16 changes: 16 additions & 0 deletions tavern/internal/www/build/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"files": {
"main.css": "/static/css/main.ed062423.css",
"main.js": "/static/js/main.1ffa92c8.js",
"static/js/787.4af0fb89.chunk.js": "/static/js/787.4af0fb89.chunk.js",
"static/media/eldrich.png": "/static/media/eldrich.a80c74e8249d2461e174.png",
"index.html": "/index.html",
"main.ed062423.css.map": "/static/css/main.ed062423.css.map",
"main.1ffa92c8.js.map": "/static/js/main.1ffa92c8.js.map",
"787.4af0fb89.chunk.js.map": "/static/js/787.4af0fb89.chunk.js.map"
},
"entrypoints": [
"static/css/main.ed062423.css",
"static/js/main.1ffa92c8.js"
]
}
9 changes: 9 additions & 0 deletions tavern/internal/www/build/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package build

import "embed"

// Content embedded from the application's build directory, includes the latest build of the UI.
//
//go:embed *.png *.html *.json *.txt *.ico
//go:embed static/*
var Content embed.FS
Binary file added tavern/internal/www/build/favicon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions tavern/internal/www/build/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.1ffa92c8.js"></script><link href="/static/css/main.ed062423.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
3 changes: 3 additions & 0 deletions tavern/internal/www/build/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tavern/internal/www/build/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions tavern/internal/www/build/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions tavern/internal/www/build/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
4 changes: 4 additions & 0 deletions tavern/internal/www/build/static/css/main.ed062423.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tavern/internal/www/build/static/css/main.ed062423.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 39be32f

Please sign in to comment.