mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-06 15:22:47 +01:00
Update generator (#37)
This commit is contained in:
131
auth.go
131
auth.go
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@@ -58,11 +57,6 @@ func (c *AuthConfig) Load(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
stateSessionCookie = "state"
|
||||
userSessionCookie = "user"
|
||||
)
|
||||
|
||||
func Authenticate(db *database.Database, config *AuthConfig) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -82,36 +76,6 @@ func Authenticate(db *database.Database, config *AuthConfig) func(next http.Hand
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func oidcCtx(w http.ResponseWriter, r *http.Request) (context.Context, context.CancelFunc) {
|
||||
if config.TLSCertFile != "" && config.TLSKeyFile != "" {
|
||||
cert, err := tls.LoadX509KeyPair(config.TLSCertFile, config.TLSKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rootCAs, _ := x509.SystemCertPool()
|
||||
if rootCAs == nil {
|
||||
rootCAs = x509.NewCertPool()
|
||||
}
|
||||
for _, c := range cert.Certificate {
|
||||
rootCAs.AppendCertsFromPEM(c)
|
||||
}
|
||||
|
||||
return oidc.ClientContext(ctx, &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: rootCAs,
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
cctx, cancel := context.WithTimeout(ctx, time.Minute)
|
||||
return cctx, cancel
|
||||
}
|
||||
*/
|
||||
|
||||
func bearerAuth(db *database.Database, authHeader string, iss string, config *AuthConfig) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -120,23 +84,9 @@ func bearerAuth(db *database.Database, authHeader string, iss string, config *Au
|
||||
return
|
||||
}
|
||||
|
||||
// oidcCtx, cancel := oidcCtx(ctx)
|
||||
// defer cancel()
|
||||
|
||||
verifier, err := config.Verifier(r.Context())
|
||||
if err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusUnauthorized, fmt.Errorf("could not verify: %w", err))
|
||||
return
|
||||
}
|
||||
authToken, err := verifier.Verify(r.Context(), authHeader[7:])
|
||||
if err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("could not verify bearer token: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
var claims map[string]interface{}
|
||||
if err := authToken.Claims(&claims); err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("failed to parse claims: %w", err))
|
||||
claims, apiError := verifyClaims(r, config, authHeader[7:])
|
||||
if apiError != nil {
|
||||
api.JSONErrorStatus(w, apiError.Status, apiError.Internal)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -145,10 +95,9 @@ func bearerAuth(db *database.Database, authHeader string, iss string, config *Au
|
||||
// return
|
||||
// }
|
||||
|
||||
b, _ := json.Marshal(claims)
|
||||
http.SetCookie(w, &http.Cookie{Name: userSessionCookie, Value: base64.StdEncoding.EncodeToString(b)})
|
||||
setClaimsCookie(w, claims)
|
||||
|
||||
r, err = setContextClaims(r, db, claims, config)
|
||||
r, err := setContextClaims(r, db, claims, config)
|
||||
if err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("could not load user: %w", err))
|
||||
return
|
||||
@@ -180,22 +129,13 @@ func keyAuth(db *database.Database, keyHeader string) func(next http.Handler) ht
|
||||
func sessionAuth(db *database.Database, config *AuthConfig) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
userCookie, err := r.Cookie(userSessionCookie)
|
||||
claims, noCookie, err := claimsCookie(r)
|
||||
if err != nil {
|
||||
api.JSONError(w, err)
|
||||
return
|
||||
}
|
||||
if noCookie {
|
||||
redirectToLogin(w, r, config.OAuth2)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(userCookie.Value)
|
||||
if err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("could not decode cookie: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
var claims map[string]interface{}
|
||||
if err := json.Unmarshal(b, &claims); err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("claims not in session"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -310,7 +250,7 @@ func redirectToLogin(w http.ResponseWriter, r *http.Request, oauth2Config *oauth
|
||||
return
|
||||
}
|
||||
|
||||
http.SetCookie(w, &http.Cookie{Name: stateSessionCookie, Value: state})
|
||||
setStateCookie(w, state)
|
||||
|
||||
http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound)
|
||||
return
|
||||
@@ -356,13 +296,13 @@ func AuthorizeRole(roles []string) func(http.Handler) http.Handler {
|
||||
|
||||
func callback(config *AuthConfig) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
stateCookie, err := r.Cookie(stateSessionCookie)
|
||||
if err != nil || stateCookie.Value == "" {
|
||||
state, err := stateCookie(r)
|
||||
if err != nil || state == "" {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("state missing"))
|
||||
return
|
||||
}
|
||||
|
||||
if stateCookie.Value != r.URL.Query().Get("state") {
|
||||
if state != r.URL.Query().Get("state") {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("state mismatch"))
|
||||
return
|
||||
}
|
||||
@@ -380,31 +320,13 @@ func callback(config *AuthConfig) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
// oidcCtx, cancel := oidcCtx(ctx)
|
||||
// defer cancel()
|
||||
|
||||
verifier, err := config.Verifier(r.Context())
|
||||
if err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusUnauthorized, fmt.Errorf("could not verify: %w", err))
|
||||
claims, apiError := verifyClaims(r, config, rawIDToken)
|
||||
if apiError != nil {
|
||||
api.JSONErrorStatus(w, apiError.Status, apiError.Internal)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse and verify ID Token payload.
|
||||
idToken, err := verifier.Verify(r.Context(), rawIDToken)
|
||||
if err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("token verification failed: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Extract custom claims
|
||||
var claims map[string]interface{}
|
||||
if err := idToken.Claims(&claims); err != nil {
|
||||
api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("claim extraction failed"))
|
||||
return
|
||||
}
|
||||
|
||||
b, _ := json.Marshal(claims)
|
||||
http.SetCookie(w, &http.Cookie{Name: userSessionCookie, Value: base64.StdEncoding.EncodeToString(b)})
|
||||
setClaimsCookie(w, claims)
|
||||
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
}
|
||||
@@ -417,3 +339,20 @@ func state() (string, error) {
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(rnd), nil
|
||||
}
|
||||
|
||||
func verifyClaims(r *http.Request, config *AuthConfig, rawIDToken string) (map[string]interface{}, *api.HTTPError) {
|
||||
verifier, err := config.Verifier(r.Context())
|
||||
if err != nil {
|
||||
return nil, &api.HTTPError{Status: http.StatusUnauthorized, Internal: fmt.Errorf("could not verify: %w", err)}
|
||||
}
|
||||
authToken, err := verifier.Verify(r.Context(), rawIDToken)
|
||||
if err != nil {
|
||||
return nil, &api.HTTPError{Status: http.StatusInternalServerError, Internal: fmt.Errorf("could not verify bearer token: %w", err)}
|
||||
}
|
||||
|
||||
var claims map[string]interface{}
|
||||
if err := authToken.Claims(&claims); err != nil {
|
||||
return nil, &api.HTTPError{Status: http.StatusInternalServerError, Internal: fmt.Errorf("failed to parse claims: %w", err)}
|
||||
}
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/database"
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
"github.com/SecurityBrewery/catalyst/role"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
)
|
||||
|
||||
type busService struct {
|
||||
|
||||
@@ -4,14 +4,13 @@ import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst"
|
||||
"github.com/SecurityBrewery/catalyst/cmd"
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/hooks"
|
||||
"github.com/SecurityBrewery/catalyst/role"
|
||||
@@ -41,18 +40,13 @@ func main() {
|
||||
}
|
||||
|
||||
// proxy static requests
|
||||
theCatalyst.Server.With(catalyst.Authenticate(theCatalyst.DB, config.Auth), catalyst.AuthorizeBlockedUser()).NotFound(proxy)
|
||||
middlewares := []func(next http.Handler) http.Handler{
|
||||
catalyst.Authenticate(theCatalyst.DB, config.Auth),
|
||||
catalyst.AuthorizeBlockedUser(),
|
||||
}
|
||||
theCatalyst.Server.With(middlewares...).NotFound(api.Proxy("http://localhost:8080"))
|
||||
|
||||
if err := http.ListenAndServe(":8000", theCatalyst.Server); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func proxy(w http.ResponseWriter, r *http.Request) {
|
||||
u, _ := url.Parse("http://localhost:8080")
|
||||
proxy := httputil.NewSingleHostReverseProxy(u)
|
||||
|
||||
r.Host = r.URL.Host
|
||||
|
||||
proxy.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/bus"
|
||||
"github.com/SecurityBrewery/catalyst/database"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/role"
|
||||
"github.com/SecurityBrewery/catalyst/storage"
|
||||
)
|
||||
|
||||
49
cookie.go
Normal file
49
cookie.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package catalyst
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
stateSessionCookie = "state"
|
||||
userSessionCookie = "user"
|
||||
)
|
||||
|
||||
func setStateCookie(w http.ResponseWriter, state string) {
|
||||
http.SetCookie(w, &http.Cookie{Name: stateSessionCookie, Value: state})
|
||||
}
|
||||
|
||||
func stateCookie(r *http.Request) (string, error) {
|
||||
stateCookie, err := r.Cookie(stateSessionCookie)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return stateCookie.Value, nil
|
||||
}
|
||||
|
||||
func setClaimsCookie(w http.ResponseWriter, claims map[string]interface{}) {
|
||||
b, _ := json.Marshal(claims)
|
||||
http.SetCookie(w, &http.Cookie{Name: userSessionCookie, Value: base64.StdEncoding.EncodeToString(b)})
|
||||
}
|
||||
|
||||
func claimsCookie(r *http.Request) (map[string]interface{}, bool, error) {
|
||||
userCookie, err := r.Cookie(userSessionCookie)
|
||||
if err != nil {
|
||||
return nil, true, nil
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(userCookie.Value)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("could not decode cookie: %w", err)
|
||||
}
|
||||
|
||||
var claims map[string]interface{}
|
||||
if err := json.Unmarshal(b, &claims); err != nil {
|
||||
return nil, false, errors.New("claims not in session")
|
||||
}
|
||||
return claims, false, err
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/bus"
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
)
|
||||
|
||||
func (db *Database) ArtifactGet(ctx context.Context, id int64, name string) (*model.Artifact, error) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/bus"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
)
|
||||
|
||||
const LogCollectionName = "logs"
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
)
|
||||
|
||||
const MigrationCollection string = "migrations"
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
)
|
||||
|
||||
type PlaybookYAML struct {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/test"
|
||||
)
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/caql"
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
"github.com/SecurityBrewery/catalyst/index"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
)
|
||||
|
||||
func toTicket(ticketForm *model.TicketForm) (interface{}, error) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/bus"
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
)
|
||||
|
||||
func (db *Database) AddArtifact(ctx context.Context, id int64, artifact *model.Artifact) (*model.TicketWithTickets, error) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/bus"
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
)
|
||||
|
||||
func (db *Database) TaskGet(ctx context.Context, id int64, playbookID string, taskID string) (*model.TicketWithTickets, *model.PlaybookResponse, *model.TaskWithContext, error) {
|
||||
|
||||
@@ -12,9 +12,9 @@ import (
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/time"
|
||||
"github.com/SecurityBrewery/catalyst/role"
|
||||
"github.com/SecurityBrewery/catalyst/time"
|
||||
)
|
||||
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_")
|
||||
|
||||
@@ -20,6 +20,7 @@ mv generated/openapi.json generated/catalyst.json
|
||||
|
||||
echo generate server and tests
|
||||
swagger-go-chi generated/community.yml generated
|
||||
rm -rf generated/auth generated/cli
|
||||
|
||||
echo generate typescript client
|
||||
openapi-generator generate -i generated/catalyst.yml -o ui/src/client -g typescript-axios --artifact-version 1.0.0-SNAPSHOT
|
||||
|
||||
1501
generated/api/api.go
1501
generated/api/api.go
File diff suppressed because it is too large
Load Diff
1129
generated/api/server.go
Executable file
1129
generated/api/server.go
Executable file
File diff suppressed because it is too large
Load Diff
25
generated/api/static.go
Executable file
25
generated/api/static.go
Executable file
@@ -0,0 +1,25 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func Static(fsys fs.FS) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
http.FileServer(http.FS(fsys)).ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func Proxy(dest string) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
u, _ := url.Parse(dest)
|
||||
proxy := httputil.NewSingleHostReverseProxy(u)
|
||||
|
||||
r.Host = r.URL.Host
|
||||
|
||||
proxy.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
0
pointer/pointer.go → generated/pointer/pointer.go
Normal file → Executable file
0
pointer/pointer.go → generated/pointer/pointer.go
Normal file → Executable file
0
time/time.go → generated/time/time.go
Normal file → Executable file
0
time/time.go → generated/time/time.go
Normal file → Executable file
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/database"
|
||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/storage"
|
||||
)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package catalyst
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -21,6 +22,7 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/role"
|
||||
"github.com/SecurityBrewery/catalyst/service"
|
||||
"github.com/SecurityBrewery/catalyst/storage"
|
||||
"github.com/SecurityBrewery/catalyst/ui"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@@ -138,10 +140,11 @@ func setupAPI(catalystService *service.Service, catalystStorage *storage.Storage
|
||||
|
||||
server.Get("/callback", callback(config.Auth))
|
||||
server.With(Authenticate(catalystDatabase, config.Auth), AuthorizeBlockedUser()).Handle("/wss", handleWebSocket(bus))
|
||||
// server.With(Authenticate(catalystDatabase, config.Auth), AuthorizeBlockedUser()).NotFound(static)
|
||||
|
||||
fsys, _ := fs.Sub(ui.UI, "dist")
|
||||
server.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("not found", r.URL.RawPath)
|
||||
Authenticate(catalystDatabase, config.Auth)(AuthorizeBlockedUser()(http.HandlerFunc(static))).ServeHTTP(w, r)
|
||||
Authenticate(catalystDatabase, config.Auth)(AuthorizeBlockedUser()(http.HandlerFunc(api.Static(fsys)))).ServeHTTP(w, r)
|
||||
})
|
||||
|
||||
return server, nil
|
||||
|
||||
22
static.go
22
static.go
@@ -1,22 +0,0 @@
|
||||
package catalyst
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/ui"
|
||||
)
|
||||
|
||||
func static(w http.ResponseWriter, r *http.Request) {
|
||||
fsys, _ := fs.Sub(ui.UI, "dist")
|
||||
|
||||
upath := strings.TrimPrefix(r.URL.Path, "/")
|
||||
|
||||
if _, err := fs.Stat(fsys, upath); err != nil {
|
||||
r.URL.Path = "/"
|
||||
r.URL.RawPath = "/"
|
||||
}
|
||||
|
||||
http.FileServer(http.FS(fsys)).ServeHTTP(w, r)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
)
|
||||
|
||||
type Storage struct {
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
"github.com/SecurityBrewery/catalyst"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
)
|
||||
|
||||
func TestBackupAndRestore(t *testing.T) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/database"
|
||||
"github.com/SecurityBrewery/catalyst/database/migrations"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
)
|
||||
|
||||
var bobSetting = &model.UserData{Email: pointer.String("bob@example.org"), Name: pointer.String("Bob Bad")}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/tidwall/sjson"
|
||||
|
||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||
ctime "github.com/SecurityBrewery/catalyst/time"
|
||||
ctime "github.com/SecurityBrewery/catalyst/generated/time"
|
||||
)
|
||||
|
||||
type testClock struct{}
|
||||
|
||||
@@ -20,9 +20,9 @@ import (
|
||||
"github.com/SecurityBrewery/catalyst/database/busdb"
|
||||
"github.com/SecurityBrewery/catalyst/generated/api"
|
||||
"github.com/SecurityBrewery/catalyst/generated/model"
|
||||
"github.com/SecurityBrewery/catalyst/generated/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/hooks"
|
||||
"github.com/SecurityBrewery/catalyst/index"
|
||||
"github.com/SecurityBrewery/catalyst/pointer"
|
||||
"github.com/SecurityBrewery/catalyst/service"
|
||||
"github.com/SecurityBrewery/catalyst/storage"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user