diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bd5d2c..df12c83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,21 +78,6 @@ jobs: - run: go tool cover -func=cover.out - uses: codecov/codecov-action@v3 - gocap: - name: gocap - runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@v3 - with: { go-version: '1.18' } - - uses: actions/checkout@v3 - - run: go mod download - - run: go install github.com/cugu/gocap@main - - run: | - mkdir -p ui/dist/img - touch ui/dist/index.html ui/dist/favicon.ico ui/dist/manifest.json ui/dist/img/fake.png - - run: go list --json ./cmd/catalyst - - run: gocap check ./cmd/catalyst - cypress: strategy: matrix: diff --git a/.golangci.yml b/.golangci.yml index aa1c8b4..c1aab84 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,6 +3,7 @@ run: timeout: 5m skip-dirs: - generated + - internal linters: enable: - asciicheck diff --git a/auth.go b/auth.go new file mode 100644 index 0000000..99f4b53 --- /dev/null +++ b/auth.go @@ -0,0 +1,98 @@ +package catalyst + +import ( + "context" + "crypto/sha256" + "errors" + "fmt" + + maut "github.com/jonas-plum/maut/auth" + + "github.com/SecurityBrewery/catalyst/database" + "github.com/SecurityBrewery/catalyst/generated/model" +) + +type catalystResolver struct { + database *database.Database +} + +func newCatalystResolver(db *database.Database) *catalystResolver { + return &catalystResolver{ + database: db, + } +} + +func (c *catalystResolver) UserCreateIfNotExists(ctx context.Context, user *maut.User, password string) (err error) { + if user != nil { + if _, err := c.database.UserGet(ctx, user.ID); err == nil { + return nil + } + } + + if user == nil || user.APIKey { + _, err = c.database.UserCreateSetupAPIKey(ctx, password) + } else { + _, err = c.database.UserCreate(ctx, &model.UserForm{ + Apikey: user.APIKey, + Blocked: user.Blocked, + ID: user.ID, + Password: &password, + Roles: user.Roles, + }) + } + + return err +} + +func (c *catalystResolver) User(ctx context.Context, userID string) (*maut.User, error) { + user, err := c.database.UserGet(ctx, userID) + if err != nil { + return nil, err + } + + return mapMautUser(user), nil +} + +func (c *catalystResolver) UserAPIKeyByHash(ctx context.Context, key string) (*maut.User, error) { + sha256Hash := fmt.Sprintf("%x", sha256.Sum256([]byte(key))) + user, err := c.database.UserAPIKeyByHash(ctx, sha256Hash) + if err != nil { + return nil, err + } + + return mapMautUser(user), nil +} + +func (c *catalystResolver) UserByIDAndPassword(ctx context.Context, username string, password string) (*maut.User, error) { + user, err := c.database.UserByIDAndPassword(ctx, username, password) + if err != nil { + return nil, err + } + + return mapMautUser(user), nil +} + +func (c *catalystResolver) Role(ctx context.Context, roleID string) (r *maut.Role, err error) { + switch roleID { + case "admin": + return Admin, nil + case "engineer": + return engineer, nil + case "analyst": + return analyst, nil + } + + return nil, errors.New("role not found") +} + +func mapMautUser(user *model.UserResponse) *maut.User { + return &maut.User{ + ID: user.ID, + APIKey: user.Apikey, + Blocked: user.Blocked, + // Email: user.Email, // TODO + // Groups: user.Groups, // TODO + // Name: user.Name, // TODO + Roles: user.Roles, + } +} diff --git a/auth/auth.go b/auth/auth.go deleted file mode 100644 index bab0aae..0000000 --- a/auth/auth.go +++ /dev/null @@ -1,475 +0,0 @@ -package auth - -import ( - "context" - "crypto/rand" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "log" - "net/http" - "strings" - "time" - - "github.com/coreos/go-oidc/v3/oidc" - "golang.org/x/exp/slices" - "golang.org/x/oauth2" - - "github.com/SecurityBrewery/catalyst/database" - "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" -) - -type Config struct { - SimpleAuthEnable bool - APIKeyAuthEnable bool - OIDCAuthEnable bool - - OIDCIssuer string - AuthURL string - OAuth2 *oauth2.Config - UserCreateConfig *UserCreateConfig - - provider *oidc.Provider -} - -type UserCreateConfig struct { - AuthBlockNew bool - AuthDefaultRoles []role.Role - AuthAdminUsers []string - - OIDCClaimUsername string - OIDCClaimEmail string - OIDCClaimName string - // OIDCClaimGroups string -} - -func (c *Config) Verifier(ctx context.Context) (*oidc.IDTokenVerifier, error) { - if c.provider == nil { - if err := c.Load(ctx); err != nil { - return nil, err - } - } - - config := &oidc.Config{ClientID: c.OAuth2.ClientID} - if c.AuthURL != "" { - config.SkipIssuerCheck = true - } - - return c.provider.Verifier(config), nil -} - -func (c *Config) Load(ctx context.Context) error { - for { - provider, err := oidc.NewProvider(ctx, c.OIDCIssuer) - if err == nil { - c.provider = provider - c.OAuth2.Endpoint = provider.Endpoint() - if c.AuthURL != "" { - c.OAuth2.Endpoint.AuthURL = c.AuthURL - } - - break - } - - if errors.Is(err, context.DeadlineExceeded) { - return errors.New("could not load provider") - } - - log.Printf("could not load oidc provider: %s, retrying in 10 seconds\n", err) - time.Sleep(time.Second * 10) - } - - return nil -} - -func Authenticate(db *database.Database, config *Config, jar *Jar) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - keyHeader := r.Header.Get("PRIVATE-TOKEN") - authHeader := r.Header.Get("Authorization") - - switch { - case keyHeader != "": - if config.APIKeyAuthEnable { - keyAuth(db, keyHeader)(next).ServeHTTP(w, r) - } else { - api.JSONErrorStatus(w, http.StatusUnauthorized, errors.New("API Key authentication not enabled")) - } - case authHeader != "": - if config.OIDCAuthEnable { - iss := config.OIDCIssuer - bearerAuth(db, authHeader, iss, config, jar)(next).ServeHTTP(w, r) - } else { - api.JSONErrorStatus(w, http.StatusUnauthorized, errors.New("OIDC authentication not enabled")) - } - default: - sessionAuth(db, config, jar)(next).ServeHTTP(w, r) - } - }) - } -} - -func bearerAuth(db *database.Database, authHeader string, iss string, config *Config, jar *Jar) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !strings.HasPrefix(authHeader, "Bearer ") { - api.JSONErrorStatus(w, http.StatusUnauthorized, errors.New("no bearer token")) - - return - } - - claims, apiError := verifyClaims(r, config, authHeader[7:]) - if apiError != nil { - api.JSONErrorStatus(w, apiError.Status, apiError.Internal) - - return - } - - // if claims.Iss != iss { - // return &api.HTTPError{Status: http.StatusInternalServerError, Internal: "wrong issuer"}) - // return - // } - - jar.setClaimsCookie(w, claims) - - r, err := setContextClaims(r, db, claims, config) - if err != nil { - api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("could not load user: %w", err)) - - return - } - - next.ServeHTTP(w, r) - }) - } -} - -func keyAuth(db *database.Database, keyHeader string) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - h := fmt.Sprintf("%x", sha256.Sum256([]byte(keyHeader))) - - key, err := db.UserAPIKeyByHash(r.Context(), h) - if err != nil { - api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("could not verify private token: %w", err)) - - return - } - - r = setContextUser(r, key, db.Hooks) - - next.ServeHTTP(w, r) - }) - } -} - -func sessionAuth(db *database.Database, config *Config, jar *Jar) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - claims, noCookie, err := jar.claimsCookie(r) - if err != nil { - deleteClaimsCookie(w) - - api.JSONError(w, err) - - return - } - if noCookie { - redirectToLogin(config, jar)(w, r) - - return - } - - r, err = setContextClaims(r, db, claims, config) - if err != nil { - api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("could not load user: %w", err)) - - return - } - - next.ServeHTTP(w, r) - }) - } -} - -func setContextClaims(r *http.Request, db *database.Database, claims map[string]any, config *Config) (*http.Request, error) { - newUser, newSetting, err := mapUserAndSettings(claims, config.UserCreateConfig) - if err != nil { - return nil, err - } - - if _, ok := busdb.UserFromContext(r.Context()); !ok { - r = busdb.SetContext(r, &model.UserResponse{ID: "auth", Roles: []string{role.Admin}, Apikey: false, Blocked: false}) - } - - user, err := db.UserGetOrCreate(r.Context(), newUser) - if err != nil { - return nil, err - } - - if _, err = db.UserDataGetOrCreate(r.Context(), newUser.ID, newSetting); err != nil { - return nil, err - } - - return setContextUser(r, user, db.Hooks), nil -} - -func setContextUser(r *http.Request, user *model.UserResponse, hooks *hooks.Hooks) *http.Request { - groups, err := hooks.GetGroups(r.Context(), user.ID) - if err == nil { - r = busdb.SetGroupContext(r, groups) - } - - return busdb.SetContext(r, user) -} - -func mapUserAndSettings(claims map[string]any, config *UserCreateConfig) (*model.UserForm, *model.UserData, error) { - // handle Bearer tokens - // if typ, ok := claims["typ"]; ok && typ == "Bearer" { - // return &model.User{ - // Username: "bot", - // Blocked: false, - // Email: pointer.String("bot@example.org"), - // Roles: []string{"user:read", "settings:read", "ticket", "backup:read", "backup:restore"}, - // Name: pointer.String("Bot"), - // }, nil - // } - - username, err := getString(claims, config.OIDCClaimUsername) - if err != nil { - return nil, nil, err - } - - email, err := getString(claims, config.OIDCClaimEmail) - if err != nil { - email = "" - } - - name, err := getString(claims, config.OIDCClaimName) - if err != nil { - name = "" - } - - roles := role.Strings(config.AuthDefaultRoles) - if slices.Contains(config.AuthAdminUsers, username) { - roles = append(roles, role.Admin) - } - - return &model.UserForm{ - ID: username, - Blocked: config.AuthBlockNew, - Roles: roles, - }, &model.UserData{ - Email: &email, - Name: &name, - }, nil -} - -func getString(m map[string]any, key string) (string, error) { - if v, ok := m[key]; ok { - if s, ok := v.(string); ok { - return s, nil - } - - return "", fmt.Errorf("mapping of %s failed, wrong type (%T)", key, v) - } - - return "", fmt.Errorf("mapping of %s failed, missing value", key) -} - -func redirectToLogin(config *Config, jar *Jar) func(http.ResponseWriter, *http.Request) { - if config.SimpleAuthEnable { - return func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/", http.StatusFound) - } - } - - if config.OIDCAuthEnable { - return redirectToOIDCLogin(config, jar) - } - - return func(writer http.ResponseWriter, request *http.Request) { - api.JSONErrorStatus(writer, http.StatusForbidden, errors.New("unauthenticated")) - } -} - -func redirectToOIDCLogin(config *Config, jar *Jar) func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - state, err := state() - if err != nil { - api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("generating state failed")) - - return - } - - jar.setStateCookie(w, state) - - http.Redirect(w, r, config.OAuth2.AuthCodeURL(state), http.StatusFound) - } -} - -func AuthorizeBlockedUser() func(http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - user, ok := busdb.UserFromContext(r.Context()) - if !ok { - api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("no user in context")) - - return - } - - if user.Blocked { - api.JSONErrorStatus(w, http.StatusForbidden, errors.New("user is blocked")) - - return - } - - next.ServeHTTP(w, r) - }) - } -} - -func AuthorizeRole(roles []string) func(http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - user, ok := busdb.UserFromContext(r.Context()) - if !ok { - api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("no user in context")) - - return - } - - if !role.UserHasRoles(user, role.FromStrings(roles)) { - api.JSONErrorStatus(w, http.StatusForbidden, fmt.Errorf("missing role %s has %s", roles, user.Roles)) - - return - } - - next.ServeHTTP(w, r) - }) - } -} - -func login(db *database.Database, jar *Jar) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - type credentials struct { - Username string - Password string - } - cr := credentials{} - - if err := json.NewDecoder(r.Body).Decode(&cr); err != nil { - api.JSONErrorStatus(w, http.StatusUnauthorized, errors.New("wrong username or password")) - - return - } - - user, err := db.UserByIDAndPassword(r.Context(), cr.Username, cr.Password) - if err != nil { - api.JSONErrorStatus(w, http.StatusUnauthorized, errors.New("wrong username or password")) - - return - } - - userdata, err := db.UserDataGet(r.Context(), user.ID) - if err != nil { - api.JSONErrorStatus(w, http.StatusUnauthorized, errors.New("no userdata")) - - return - } - - jar.setClaimsCookie(w, map[string]any{ - "preferred_username": user.ID, - "name": userdata.Name, - "email": userdata.Email, - }) - - b, _ := json.Marshal(map[string]string{"login": "successful"}) - _, _ = w.Write(b) - } -} - -func logout() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - deleteClaimsCookie(w) - - http.Redirect(w, r, "/", http.StatusFound) - } -} - -func callback(config *Config, jar *Jar) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - state, err := jar.stateCookie(r) - if err != nil || state == "" { - api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("state missing")) - - return - } - - if state != r.URL.Query().Get("state") { - api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("state mismatch")) - - return - } - - oauth2Token, err := config.OAuth2.Exchange(r.Context(), r.URL.Query().Get("code")) - if err != nil { - api.JSONErrorStatus(w, http.StatusInternalServerError, fmt.Errorf("oauth2 exchange failed: %w", err)) - - return - } - - // Extract the ID Token from OAuth2 token. - rawIDToken, ok := oauth2Token.Extra("id_token").(string) - if !ok { - api.JSONErrorStatus(w, http.StatusInternalServerError, errors.New("missing id token")) - - return - } - - claims, apiError := verifyClaims(r, config, rawIDToken) - if apiError != nil { - api.JSONErrorStatus(w, apiError.Status, apiError.Internal) - - return - } - - jar.setClaimsCookie(w, claims) - - http.Redirect(w, r, "/ui/", http.StatusFound) - } -} - -func state() (string, error) { - rnd := make([]byte, 32) - if _, err := rand.Read(rnd); err != nil { - return "", err - } - - return base64.URLEncoding.EncodeToString(rnd), nil -} - -func verifyClaims(r *http.Request, config *Config, rawIDToken string) (map[string]any, *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]any - 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 -} diff --git a/auth/cookie.go b/auth/cookie.go deleted file mode 100644 index 78a5ca2..0000000 --- a/auth/cookie.go +++ /dev/null @@ -1,84 +0,0 @@ -package auth - -import ( - "log" - "net/http" - - "github.com/gorilla/securecookie" - "golang.org/x/crypto/argon2" - - "github.com/SecurityBrewery/catalyst/generated/time" -) - -const ( - stateSessionCookie = "state" - userSessionCookie = "user" -) - -type Jar struct { - store *securecookie.SecureCookie -} - -func NewJar(secret []byte) *Jar { - hashSalt := securecookie.GenerateRandomKey(64) - blockSalt := securecookie.GenerateRandomKey(64) - - return &Jar{ - store: securecookie.New( - argon2.IDKey(secret, hashSalt, 1, 64*1024, 4, 64), - argon2.IDKey(secret, blockSalt, 1, 64*1024, 4, 32), - ), - } -} - -func (j *Jar) setStateCookie(w http.ResponseWriter, state string) { - encoded, err := j.store.Encode(userSessionCookie, state) - if err != nil { - log.Println(err) - - return - } - - tomorrow := time.Now().AddDate(0, 0, 1) - http.SetCookie(w, &http.Cookie{Name: stateSessionCookie, Value: encoded, Path: "/", Expires: tomorrow}) -} - -func (j *Jar) stateCookie(r *http.Request) (string, error) { - stateCookie, err := r.Cookie(stateSessionCookie) - if err != nil { - return "", err - } - - var state string - err = j.store.Decode(userSessionCookie, stateCookie.Value, &state) - - return state, err -} - -func (j *Jar) setClaimsCookie(w http.ResponseWriter, claims map[string]any) { - encoded, err := j.store.Encode(userSessionCookie, claims) - if err != nil { - log.Println(err) - - return - } - - tomorrow := time.Now().AddDate(0, 0, 1) - http.SetCookie(w, &http.Cookie{Name: userSessionCookie, Value: encoded, Path: "/", Expires: tomorrow}) -} - -func deleteClaimsCookie(w http.ResponseWriter) { - http.SetCookie(w, &http.Cookie{Name: userSessionCookie, Value: "", MaxAge: -1}) -} - -func (j *Jar) claimsCookie(r *http.Request) (map[string]any, bool, error) { - userCookie, err := r.Cookie(userSessionCookie) - if err != nil { - return nil, true, nil - } - - var claims map[string]any - err = j.store.Decode(userSessionCookie, userCookie.Value, &claims) - - return claims, false, err -} diff --git a/auth/server.go b/auth/server.go deleted file mode 100644 index 178b085..0000000 --- a/auth/server.go +++ /dev/null @@ -1,43 +0,0 @@ -package auth - -import ( - "encoding/json" - "net/http" - - "github.com/go-chi/chi/v5" - - "github.com/SecurityBrewery/catalyst/database" -) - -func Server(config *Config, catalystDatabase *database.Database, jar *Jar) *chi.Mux { - server := chi.NewRouter() - - server.Get("/config", hasOIDC(config)) - - if config.OIDCAuthEnable { - server.Get("/callback", callback(config, jar)) - server.Get("/oidclogin", redirectToOIDCLogin(config, jar)) - } - if config.SimpleAuthEnable { - server.Post("/login", login(catalystDatabase, jar)) - } - server.Post("/logout", logout()) - - return server -} - -func hasOIDC(config *Config) func(writer http.ResponseWriter, request *http.Request) { - return func(writer http.ResponseWriter, request *http.Request) { - b, err := json.Marshal(map[string]any{ - "simple": config.SimpleAuthEnable, - "oidc": config.OIDCAuthEnable, - }) - if err != nil { - writer.WriteHeader(http.StatusInternalServerError) - - return - } - - _, _ = writer.Write(b) - } -} diff --git a/busservice/busservice.go b/busservice/busservice.go index 4fc0af0..da951f9 100644 --- a/busservice/busservice.go +++ b/busservice/busservice.go @@ -4,12 +4,12 @@ import ( "context" "log" + maut "github.com/jonas-plum/maut/auth" + "github.com/SecurityBrewery/catalyst/bus" "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" ) type busService struct { @@ -30,9 +30,9 @@ func New(apiURL, apikey, network string, catalystBus *bus.Bus, db *database.Data func busContext() context.Context { // TODO: change roles? - bot := &model.UserResponse{ID: "bot", Roles: []string{role.Admin}} + bot := &maut.User{ID: "bot", Roles: []string{maut.AdminRole}} - return busdb.UserContext(context.Background(), bot) + return maut.UserContext(context.Background(), bot, nil) // TODO add permissions ? } func (h *busService) logRequest(msg *bus.RequestMsg) { diff --git a/cmd/catalyst-dev/main.go b/cmd/catalyst-dev/main.go index ed902fd..1912e37 100644 --- a/cmd/catalyst-dev/main.go +++ b/cmd/catalyst-dev/main.go @@ -8,15 +8,14 @@ import ( "time" "github.com/arangodb/go-driver" + maut "github.com/jonas-plum/maut/auth" "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/generated/pointer" "github.com/SecurityBrewery/catalyst/hooks" - "github.com/SecurityBrewery/catalyst/role" "github.com/SecurityBrewery/catalyst/test" ) @@ -36,8 +35,8 @@ func main() { log.Fatal(err) } - demoUser := &model.UserResponse{ID: "demo", Roles: []string{role.Admin}} - ctx := busdb.UserContext(context.Background(), demoUser) + demoUser := &maut.User{ID: "demo", Roles: []string{maut.AdminRole}} + ctx := maut.UserContext(context.Background(), demoUser, catalyst.Admin.Permissions) if err := test.SetupTestData(ctx, theCatalyst.DB); err != nil { log.Fatal(err) } diff --git a/cmd/cmd.go b/cmd/cmd.go index 93af75c..8fdf24e 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -6,13 +6,12 @@ import ( "github.com/alecthomas/kong" kongyaml "github.com/alecthomas/kong-yaml" "github.com/coreos/go-oidc/v3/oidc" + maut "github.com/jonas-plum/maut/auth" "golang.org/x/exp/slices" "golang.org/x/oauth2" "github.com/SecurityBrewery/catalyst" - "github.com/SecurityBrewery/catalyst/auth" "github.com/SecurityBrewery/catalyst/database" - "github.com/SecurityBrewery/catalyst/role" "github.com/SecurityBrewery/catalyst/storage" ) @@ -73,10 +72,6 @@ func ParseCatalystConfig() (*catalyst.Config, error) { } func MapConfig(cli CLI) (*catalyst.Config, error) { - roles := role.Explode(role.Analyst) - roles = append(roles, role.Explodes(cli.AuthDefaultRoles)...) - roles = role.Explodes(role.Strings(roles)) - scopes := slices.Compact(append([]string{oidc.ScopeOpenID, "profile", "email"}, cli.OIDCScopes...)) config := &catalyst.Config{ IndexPath: cli.IndexPath, @@ -87,32 +82,34 @@ func MapConfig(cli CLI) (*catalyst.Config, error) { Password: cli.ArangoDBPassword, }, Storage: &storage.Config{Host: cli.S3Host, User: cli.S3User, Password: cli.S3Password}, - Secret: []byte(cli.Secret), ExternalAddress: cli.ExternalAddress, InternalAddress: cli.CatalystAddress, Port: cli.Port, - Auth: &auth.Config{ + Auth: &maut.Config{ + CookieSecret: []byte(cli.Secret), SimpleAuthEnable: false, // cli.SimpleAuthEnable, APIKeyAuthEnable: cli.APIKeyAuthEnable, OIDCAuthEnable: cli.OIDCEnable, - OIDCIssuer: cli.OIDCIssuer, - AuthURL: cli.AuthURL, + // InitialUser: "", + // InitialPassword: "", + InitialAPIKey: cli.InitialAPIKey, + OIDCIssuer: cli.OIDCIssuer, + AuthURL: cli.AuthURL, OAuth2: &oauth2.Config{ ClientID: cli.OIDCClientID, ClientSecret: cli.OIDCClientSecret, RedirectURL: cli.ExternalAddress + "/auth/callback", Scopes: scopes, }, - UserCreateConfig: &auth.UserCreateConfig{ + UserCreateConfig: &maut.UserCreateConfig{ AuthBlockNew: cli.AuthBlockNew, - AuthDefaultRoles: roles, + AuthDefaultRoles: cli.AuthDefaultRoles, AuthAdminUsers: cli.AuthAdminUsers, OIDCClaimUsername: cli.OIDCClaimUsername, OIDCClaimEmail: cli.OIDCClaimEmail, OIDCClaimName: cli.OIDCClaimName, }, }, - InitialAPIKey: cli.InitialAPIKey, } return config, nil diff --git a/database/busdb/context.go b/database/busdb/context.go deleted file mode 100644 index 43e9943..0000000 --- a/database/busdb/context.go +++ /dev/null @@ -1,38 +0,0 @@ -package busdb - -import ( - "context" - "net/http" - - "github.com/SecurityBrewery/catalyst/generated/model" - "github.com/SecurityBrewery/catalyst/role" -) - -type contextKey string - -const ( - userContextKey contextKey = "user" - groupContextKey contextKey = "groups" -) - -func SetContext(r *http.Request, user *model.UserResponse) *http.Request { - user.Roles = role.Strings(role.Explodes(user.Roles)) - - return r.WithContext(context.WithValue(r.Context(), userContextKey, user)) -} - -func SetGroupContext(r *http.Request, groups []string) *http.Request { - return r.WithContext(context.WithValue(r.Context(), groupContextKey, groups)) -} - -func UserContext(ctx context.Context, user *model.UserResponse) context.Context { - user.Roles = role.Strings(role.Explodes(user.Roles)) - - return context.WithValue(ctx, userContextKey, user) -} - -func UserFromContext(ctx context.Context) (*model.UserResponse, bool) { - u, ok := ctx.Value(userContextKey).(*model.UserResponse) - - return u, ok -} diff --git a/database/busdb/log.go b/database/busdb/log.go index 0af9645..6908a53 100644 --- a/database/busdb/log.go +++ b/database/busdb/log.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/arangodb/go-driver" + maut "github.com/jonas-plum/maut/auth" "github.com/SecurityBrewery/catalyst/bus" "github.com/SecurityBrewery/catalyst/generated/model" @@ -15,7 +16,7 @@ import ( const LogCollectionName = "logs" func (db *BusDatabase) LogCreate(ctx context.Context, logType, reference, message string) (*model.LogEntry, error) { - user, ok := UserFromContext(ctx) + user, _, ok := maut.UserFromContext(ctx) if !ok { return nil, errors.New("no user in context") } diff --git a/database/migrations/migrations.go b/database/migrations/migrations.go index e0cfe76..fb7ce95 100644 --- a/database/migrations/migrations.go +++ b/database/migrations/migrations.go @@ -62,6 +62,8 @@ func generateMigrations() ([]Migration, error) { &updateDocument[model.Settings]{ID: "update-settings-global-1", Collection: "settings", Key: "global", Document: &model.Settings{ArtifactStates: []*model.Type{{Icon: "mdi-help-circle-outline", ID: "unknown", Name: "Unknown", Color: pointer.String(model.TypeColorInfo)}, {Icon: "mdi-skull", ID: "malicious", Name: "Malicious", Color: pointer.String(model.TypeColorError)}, {Icon: "mdi-check", ID: "clean", Name: "Clean", Color: pointer.String(model.TypeColorSuccess)}}, ArtifactKinds: []*model.Type{{Icon: "mdi-server", ID: "asset", Name: "Asset"}, {Icon: "mdi-bullseye", ID: "ioc", Name: "IOC"}}, Timeformat: "yyyy-MM-dd hh:mm:ss"}}, &updateSchema{ID: "update-user-simple-login", Name: "users", DataType: "user", Schema: `{"type":"object","properties":{"apikey":{"type":"boolean"},"blocked":{"type":"boolean"},"roles":{"items":{"type":"string"},"type":"array"},"salt":{"type":"string"},"sha256":{"type":"string"},"sha512":{"type":"string"}},"required":["blocked","apikey","roles"],"$id":"#/definitions/User"}`}, + + &mapRoles{ID: "simplify-roles"}, }, nil } @@ -232,3 +234,17 @@ func (m *updateDocument[T]) Migrate(ctx context.Context, driver driver.Database) return err } + +type mapRoles struct { + ID string +} + +func (m mapRoles) MID() string { + return m.ID +} + +func (m mapRoles) Migrate(ctx context.Context, driver driver.Database) error { + _, err := driver.Query(ctx, "FOR u IN users UPDATE u WITH {roles: u.roles[*].name} IN users", nil) + + return err +} diff --git a/database/ticket_field.go b/database/ticket_field.go index aa95994..b460bb4 100644 --- a/database/ticket_field.go +++ b/database/ticket_field.go @@ -7,6 +7,7 @@ import ( "github.com/arangodb/go-driver" "github.com/iancoleman/strcase" + maut "github.com/jonas-plum/maut/auth" "github.com/mingrammer/commonregex" "github.com/SecurityBrewery/catalyst/bus" @@ -110,7 +111,7 @@ func (db *Database) AddComment(ctx context.Context, id int64, comment *model.Com } if comment.Creator == nil || *comment.Creator == "" { - user, exists := busdb.UserFromContext(ctx) + user, _, exists := maut.UserFromContext(ctx) if !exists { return nil, errors.New("no user in context") } diff --git a/database/user.go b/database/user.go index 4823f6c..5b7f9a7 100644 --- a/database/user.go +++ b/database/user.go @@ -11,12 +11,12 @@ import ( "github.com/arangodb/go-driver" "github.com/iancoleman/strcase" + maut "github.com/jonas-plum/maut/auth" "github.com/SecurityBrewery/catalyst/database/busdb" "github.com/SecurityBrewery/catalyst/generated/model" "github.com/SecurityBrewery/catalyst/generated/pointer" "github.com/SecurityBrewery/catalyst/generated/time" - "github.com/SecurityBrewery/catalyst/role" ) var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_") @@ -35,11 +35,9 @@ func generateKey() string { } func toUser(user *model.UserForm, salt, sha256, sha512 *string) *model.User { - roles := []string{} - roles = append(roles, role.Strings(role.Explodes(user.Roles))...) u := &model.User{ Blocked: user.Blocked, - Roles: roles, + Roles: user.Roles, Salt: salt, Sha256: sha256, Sha512: sha512, @@ -94,7 +92,7 @@ func (db *Database) UserCreate(ctx context.Context, newUser *model.UserForm) (*m var key, salt, sha256Hash, sha512Hash *string if newUser.Apikey { key, sha256Hash = generateAPIKey() - } else { + } else if newUser.Password != nil { salt, sha512Hash = hashUserPassword(newUser) } @@ -111,7 +109,7 @@ func (db *Database) UserCreate(ctx context.Context, newUser *model.UserForm) (*m func (db *Database) UserCreateSetupAPIKey(ctx context.Context, key string) (*model.UserResponse, error) { newUser := &model.UserForm{ ID: "setup", - Roles: []string{role.Admin}, + Roles: []string{maut.AdminRole}, Apikey: true, Blocked: false, } diff --git a/definition/settings.yaml b/definition/settings.yaml index ac5ca85..2564233 100644 --- a/definition/settings.yaml +++ b/definition/settings.yaml @@ -28,16 +28,6 @@ paths: - { icon: "mdi-help-circle-outline", id: "unknown", name: "Unknown", color: "info" } - { icon: "mdi-skull", id: "malicious", name: "Malicious", color: "error" } - { icon: "mdi-check", id: "clean", name: "Clean", color: "success" } - roles: [ - "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", - "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", - "admin:userdata:write", "analyst:automation:read", - "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", - "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", - "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", - "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", - "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", - "engineer:tickettype:write" ] security: [ { roles: [ "settings:read" ] } ] post: tags: [ "settings" ] @@ -66,16 +56,6 @@ paths: - { icon: "mdi-help-circle-outline", id: "unknown", name: "Unknown", color: "info" } - { icon: "mdi-skull", id: "malicious", name: "Malicious", color: "error" } - { icon: "mdi-check", id: "clean", name: "Clean", color: "success" } - roles: [ - "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", - "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", - "admin:userdata:write", "analyst:automation:read", - "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", - "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", - "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", - "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", - "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", - "engineer:tickettype:write" ] security: [ { roles: [ "settings:write" ] } ] definitions: diff --git a/definition/users.yaml b/definition/users.yaml index ff49940..5f05d60 100644 --- a/definition/users.yaml +++ b/definition/users.yaml @@ -12,7 +12,7 @@ paths: description: "successful operation" schema: { $ref: "#/definitions/UserResponse" } examples: - test: { id: bob, roles: [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read","analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: false } + test: { id: bob, roles: [ "admin" ], blocked: false, apikey: false } security: [ { roles: [ "currentuser:read" ] } ] /users: @@ -26,8 +26,8 @@ paths: schema: { type: array, items: { $ref: "#/definitions/UserResponse" } } examples: test: - - { id: bob, blocked: false, roles: [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], apikey: false } - - { id: script, roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: true } + - { id: bob, blocked: false, roles: [ "admin" ], apikey: false } + - { id: script, roles: [ "engineer" ], blocked: false, apikey: true } security: [ { roles: [ "user:read" ] } ] post: tags: [ "users" ] @@ -40,7 +40,7 @@ paths: description: "successful operation" schema: { $ref: "#/definitions/NewUserResponse" } examples: - test: { id: "syncscript", roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], secret: "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH", blocked: false } + test: { id: "syncscript", roles: [ "analyst" ], secret: "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH", blocked: false } security: [ { roles: [ "user:write" ] } ] /users/{id}: get: @@ -54,7 +54,7 @@ paths: description: "successful operation" schema: { $ref: "#/definitions/UserResponse" } examples: - test: { id: "script", roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: true } + test: { id: "script", roles: [ "engineer" ], blocked: false, apikey: true } security: [ { roles: [ "user:read" ] } ] put: tags: [ "users" ] @@ -70,7 +70,7 @@ paths: examples: test: id: bob - roles: [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + roles: [ "analyst", "admin" ] apikey: false blocked: false security: [ { roles: [ "user:write" ] } ] diff --git a/file.go b/file.go index 646739e..0f77641 100644 --- a/file.go +++ b/file.go @@ -14,12 +14,12 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/go-chi/chi/v5" + maut "github.com/jonas-plum/maut/auth" tusd "github.com/tus/tusd/pkg/handler" "github.com/tus/tusd/pkg/s3store" "github.com/SecurityBrewery/catalyst/bus" "github.com/SecurityBrewery/catalyst/database" - "github.com/SecurityBrewery/catalyst/database/busdb" "github.com/SecurityBrewery/catalyst/generated/api" "github.com/SecurityBrewery/catalyst/generated/model" "github.com/SecurityBrewery/catalyst/storage" @@ -57,7 +57,7 @@ func tusdUpload(db *database.Database, catalystBus *bus.Bus, client *s3.S3, exte } userID := "unknown" - user, ok := busdb.UserFromContext(r.Context()) + user, _, ok := maut.UserFromContext(r.Context()) if ok { userID = user.ID } diff --git a/generate.sh b/generate.sh index 90cba6e..62a084e 100644 --- a/generate.sh +++ b/generate.sh @@ -23,6 +23,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 +find generated -type f -name "*.go" -print0 | xargs -0 sed -i '' -e 's#"github.com/go-chi/chi"#"github.com/go-chi/chi/v5"#g' echo generate typescript client openapi-generator generate -i generated/catalyst.yml -o ui/src/client -g typescript-axios --artifact-version 1.0.0-SNAPSHOT @@ -34,3 +35,6 @@ rm -rf ui/src/client/.openapi-generator ui/src/client/git_push.sh ui/src/client/ go mod tidy gci write --Section Standard --Section Default --Section "Prefix(github.com/SecurityBrewery/catalyst)" . +cd internal/maut +gci write --Section Standard --Section Default --Section "Prefix(github.com/jonas-plum/maut)" . +cd ../.. diff --git a/generated/api/api.go b/generated/api/api.go index 3c10c56..389655e 100755 --- a/generated/api/api.go +++ b/generated/api/api.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "strconv" - "strings" "github.com/go-chi/chi/v5" "github.com/xeipuuv/gojsonschema" @@ -59,12 +58,30 @@ func parseQueryBool(r *http.Request, s string) (bool, error) { } func parseQueryStringArray(r *http.Request, key string) ([]string, error) { - return parseQueryArray(r, key), nil + stringArray, ok := r.URL.Query()[key] + if !ok { + return nil, nil + } + return removeEmpty(stringArray), nil +} + +func removeEmpty(l []string) []string { + var stringArray []string + for _, s := range l { + if s == "" { + continue + } + stringArray = append(stringArray, s) + } + + return stringArray } func parseQueryBoolArray(r *http.Request, key string) ([]bool, error) { - stringArray := parseQueryArray(r, key) - + stringArray, ok := r.URL.Query()[key] + if !ok { + return nil, nil + } var boolArray []bool for _, s := range stringArray { if s == "" { @@ -80,33 +97,6 @@ func parseQueryBoolArray(r *http.Request, key string) ([]bool, error) { return boolArray, nil } -func parseQueryArray(r *http.Request, key string) []string { - stringArray, ok := r.URL.Query()[key] - if !ok { - return nil - } - - if len(stringArray) == 0 { - return nil - } - - stringArray = strings.Split(stringArray[0], ",") - - return removeEmpty(stringArray) -} - -func removeEmpty(l []string) []string { - var stringArray []string - for _, s := range l { - if s == "" { - continue - } - stringArray = append(stringArray, s) - } - - return stringArray -} - func parseQueryOptionalInt(r *http.Request, key string) (*int, error) { s := r.URL.Query().Get(key) if s == "" { diff --git a/generated/api/api_test.go b/generated/api/api_test.go deleted file mode 100644 index a085545..0000000 --- a/generated/api/api_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package api - -import ( - "net/http" - "net/http/httptest" - "reflect" - "testing" -) - -func Test_parseQueryOptionalBoolArray(t *testing.T) { - type args struct { - r *http.Request - key string - } - tests := []struct { - name string - args args - want []bool - wantErr bool - }{ - { - name: "bool array", - args: args{ - r: httptest.NewRequest( - http.MethodGet, - "https://try.catalyst-soar.com/api/tickets?type=alert&offset=0&count=10&sort=status%2Cowner%2Ccreated&desc=true%2Cfalse%2Cfalse&query=status+%3D%3D+%27open%27+AND+%28owner+%3D%3D+%27eve%27+OR+%21owner%29", - nil, - ), - key: "desc", - }, - want: []bool{true, false, false}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := parseQueryOptionalBoolArray(tt.args.r, tt.args.key) - if (err != nil) != tt.wantErr { - t.Errorf("parseQueryOptionalBoolArray() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("parseQueryOptionalBoolArray() got = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_parseQueryOptionalStringArray(t *testing.T) { - type args struct { - r *http.Request - key string - } - tests := []struct { - name string - args args - want []string - wantErr bool - }{ - { - name: "string array", - args: args{ - r: httptest.NewRequest( - http.MethodGet, - "https://try.catalyst-soar.com/api/tickets?type=alert&offset=0&count=10&sort=status%2Cowner%2Ccreated&desc=true%2Cfalse%2Cfalse&query=status+%3D%3D+%27open%27+AND+%28owner+%3D%3D+%27eve%27+OR+%21owner%29", - nil, - ), - key: "sort", - }, - want: []string{"status", "owner", "created"}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := parseQueryOptionalStringArray(tt.args.r, tt.args.key) - if (err != nil) != tt.wantErr { - t.Errorf("parseQueryOptionalStringArray() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("parseQueryOptionalStringArray() got = %v, want %v", got, tt.want) - } - }) - } -} \ No newline at end of file diff --git a/generated/api/test_api.go b/generated/api/test_api.go index 585f3bc..1dae84d 100755 --- a/generated/api/test_api.go +++ b/generated/api/test_api.go @@ -68,7 +68,7 @@ var Tests = []struct { Args: Args{Method: "Get", URL: "/currentuser"}, Want: Want{ Status: 200, - Body: map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, + Body: map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin"}}, }, }, @@ -239,7 +239,7 @@ var Tests = []struct { Args: Args{Method: "Get", URL: "/settings"}, Want: Want{ Status: 200, - Body: map[string]interface{}{"artifactKinds": []interface{}{map[string]interface{}{"icon": "mdi-server", "id": "asset", "name": "Asset"}, map[string]interface{}{"icon": "mdi-bullseye", "id": "ioc", "name": "IOC"}}, "artifactStates": []interface{}{map[string]interface{}{"color": "info", "icon": "mdi-help-circle-outline", "id": "unknown", "name": "Unknown"}, map[string]interface{}{"color": "error", "icon": "mdi-skull", "id": "malicious", "name": "Malicious"}, map[string]interface{}{"color": "success", "icon": "mdi-check", "id": "clean", "name": "Clean"}}, "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}, "ticketTypes": []interface{}{map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-radioactive", "id": "incident", "name": "Incidents"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-fingerprint", "id": "investigation", "name": "Forensic Investigations"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-target", "id": "hunt", "name": "Threat Hunting"}}, "tier": "community", "timeformat": "yyyy-MM-dd hh:mm:ss", "version": "0.0.0-test"}, + Body: map[string]interface{}{"artifactKinds": []interface{}{map[string]interface{}{"icon": "mdi-server", "id": "asset", "name": "Asset"}, map[string]interface{}{"icon": "mdi-bullseye", "id": "ioc", "name": "IOC"}}, "artifactStates": []interface{}{map[string]interface{}{"color": "info", "icon": "mdi-help-circle-outline", "id": "unknown", "name": "Unknown"}, map[string]interface{}{"color": "error", "icon": "mdi-skull", "id": "malicious", "name": "Malicious"}, map[string]interface{}{"color": "success", "icon": "mdi-check", "id": "clean", "name": "Clean"}}, "ticketTypes": []interface{}{map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-radioactive", "id": "incident", "name": "Incidents"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-fingerprint", "id": "investigation", "name": "Forensic Investigations"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-target", "id": "hunt", "name": "Threat Hunting"}}, "tier": "community", "timeformat": "yyyy-MM-dd hh:mm:ss", "version": "0.0.0-test"}, }, }, @@ -248,7 +248,7 @@ var Tests = []struct { Args: Args{Method: "Post", URL: "/settings", Data: map[string]interface{}{"artifactKinds": []interface{}{map[string]interface{}{"icon": "mdi-server", "id": "asset", "name": "Asset"}, map[string]interface{}{"icon": "mdi-bullseye", "id": "ioc", "name": "IOC"}}, "artifactStates": []interface{}{map[string]interface{}{"color": "info", "icon": "mdi-help-circle-outline", "id": "unknown", "name": "Unknown"}, map[string]interface{}{"color": "error", "icon": "mdi-skull", "id": "malicious", "name": "Malicious"}, map[string]interface{}{"color": "success", "icon": "mdi-check", "id": "clean", "name": "Clean"}}, "timeformat": "yyyy-MM-dd hh:mm:ss"}}, Want: Want{ Status: 200, - Body: map[string]interface{}{"artifactKinds": []interface{}{map[string]interface{}{"icon": "mdi-server", "id": "asset", "name": "Asset"}, map[string]interface{}{"icon": "mdi-bullseye", "id": "ioc", "name": "IOC"}}, "artifactStates": []interface{}{map[string]interface{}{"color": "info", "icon": "mdi-help-circle-outline", "id": "unknown", "name": "Unknown"}, map[string]interface{}{"color": "error", "icon": "mdi-skull", "id": "malicious", "name": "Malicious"}, map[string]interface{}{"color": "success", "icon": "mdi-check", "id": "clean", "name": "Clean"}}, "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}, "ticketTypes": []interface{}{map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-radioactive", "id": "incident", "name": "Incidents"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-fingerprint", "id": "investigation", "name": "Forensic Investigations"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-target", "id": "hunt", "name": "Threat Hunting"}}, "tier": "community", "timeformat": "yyyy-MM-dd hh:mm:ss", "version": "0.0.0-test"}, + Body: map[string]interface{}{"artifactKinds": []interface{}{map[string]interface{}{"icon": "mdi-server", "id": "asset", "name": "Asset"}, map[string]interface{}{"icon": "mdi-bullseye", "id": "ioc", "name": "IOC"}}, "artifactStates": []interface{}{map[string]interface{}{"color": "info", "icon": "mdi-help-circle-outline", "id": "unknown", "name": "Unknown"}, map[string]interface{}{"color": "error", "icon": "mdi-skull", "id": "malicious", "name": "Malicious"}, map[string]interface{}{"color": "success", "icon": "mdi-check", "id": "clean", "name": "Clean"}}, "ticketTypes": []interface{}{map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-alert", "id": "alert", "name": "Alerts"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-radioactive", "id": "incident", "name": "Incidents"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-fingerprint", "id": "investigation", "name": "Forensic Investigations"}, map[string]interface{}{"default_playbooks": []interface{}{}, "default_template": "default", "icon": "mdi-target", "id": "hunt", "name": "Threat Hunting"}}, "tier": "community", "timeformat": "yyyy-MM-dd hh:mm:ss", "version": "0.0.0-test"}, }, }, @@ -608,7 +608,7 @@ var Tests = []struct { Args: Args{Method: "Get", URL: "/users"}, Want: Want{ Status: 200, - Body: []interface{}{map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, map[string]interface{}{"apikey": true, "blocked": false, "id": "script", "roles": []interface{}{"analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}}, + Body: []interface{}{map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin"}}, map[string]interface{}{"apikey": true, "blocked": false, "id": "script", "roles": []interface{}{"engineer"}}}, }, }, @@ -617,7 +617,7 @@ var Tests = []struct { Args: Args{Method: "Post", URL: "/users", Data: map[string]interface{}{"apikey": true, "blocked": false, "id": "syncscript", "roles": []interface{}{"analyst"}}}, Want: Want{ Status: 200, - Body: map[string]interface{}{"blocked": false, "id": "syncscript", "roles": []interface{}{"analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read"}, "secret": "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH"}, + Body: map[string]interface{}{"blocked": false, "id": "syncscript", "roles": []interface{}{"analyst"}, "secret": "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH"}, }, }, @@ -626,7 +626,7 @@ var Tests = []struct { Args: Args{Method: "Get", URL: "/users/script"}, Want: Want{ Status: 200, - Body: map[string]interface{}{"apikey": true, "blocked": false, "id": "script", "roles": []interface{}{"analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, + Body: map[string]interface{}{"apikey": true, "blocked": false, "id": "script", "roles": []interface{}{"engineer"}}, }, }, @@ -635,7 +635,7 @@ var Tests = []struct { Args: Args{Method: "Put", URL: "/users/bob", Data: map[string]interface{}{"apikey": false, "blocked": false, "id": "syncscript", "roles": []interface{}{"analyst", "admin"}}}, Want: Want{ Status: 200, - Body: map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write"}}, + Body: map[string]interface{}{"apikey": false, "blocked": false, "id": "bob", "roles": []interface{}{"analyst", "admin"}}, }, }, diff --git a/generated/catalyst.json b/generated/catalyst.json index 07d5972..c02657d 100644 --- a/generated/catalyst.json +++ b/generated/catalyst.json @@ -225,7 +225,7 @@ "apikey" : false, "blocked" : false, "id" : "bob", - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "admin" ] } } }, @@ -1424,7 +1424,6 @@ "id" : "clean", "name" : "Clean" } ], - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], "ticketTypes" : [ { "default_playbooks" : [ ], "default_template" : "default", @@ -1513,7 +1512,6 @@ "id" : "clean", "name" : "Clean" } ], - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], "ticketTypes" : [ { "default_playbooks" : [ ], "default_template" : "default", @@ -5343,12 +5341,12 @@ "apikey" : false, "blocked" : false, "id" : "bob", - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "admin" ] }, { "apikey" : true, "blocked" : false, "id" : "script", - "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "engineer" ] } ] } }, @@ -5386,7 +5384,7 @@ "example" : { "blocked" : false, "id" : "syncscript", - "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], + "roles" : [ "analyst" ], "secret" : "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH" } } @@ -5452,7 +5450,7 @@ "apikey" : true, "blocked" : false, "id" : "script", - "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "engineer" ] } } }, @@ -5501,7 +5499,7 @@ "apikey" : false, "blocked" : false, "id" : "bob", - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "analyst", "admin" ] } } }, diff --git a/generated/catalyst.yml b/generated/catalyst.yml index db588fc..02ed724 100644 --- a/generated/catalyst.yml +++ b/generated/catalyst.yml @@ -1631,38 +1631,7 @@ paths: blocked: false id: bob roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - admin schema: $ref: '#/definitions/UserResponse' security: @@ -2834,39 +2803,6 @@ paths: icon: mdi-check id: clean name: Clean - roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write ticketTypes: - default_playbooks: [] default_template: default @@ -2955,39 +2891,6 @@ paths: icon: mdi-check id: clean name: Clean - roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write ticketTypes: - default_playbooks: [] default_template: default @@ -7360,62 +7263,12 @@ paths: blocked: false id: bob roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - admin - apikey: true blocked: false id: script roles: - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - engineer schema: items: $ref: '#/definitions/UserResponse' @@ -7449,21 +7302,7 @@ paths: blocked: false id: syncscript roles: - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read + - analyst secret: v39bOuobnlEljfWzjAgoKzhmnh1xSMxH schema: $ref: '#/definitions/NewUserResponse' @@ -7510,26 +7349,7 @@ paths: blocked: false id: script roles: - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - engineer schema: $ref: '#/definitions/UserResponse' security: @@ -7569,38 +7389,8 @@ paths: blocked: false id: bob roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - analyst + - admin schema: $ref: '#/definitions/UserResponse' security: diff --git a/generated/community.json b/generated/community.json index f527f50..711d88a 100644 --- a/generated/community.json +++ b/generated/community.json @@ -225,7 +225,7 @@ "apikey" : false, "blocked" : false, "id" : "bob", - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "admin" ] } } }, @@ -994,7 +994,6 @@ "id" : "clean", "name" : "Clean" } ], - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], "ticketTypes" : [ { "default_playbooks" : [ ], "default_template" : "default", @@ -1083,7 +1082,6 @@ "id" : "clean", "name" : "Clean" } ], - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], "ticketTypes" : [ { "default_playbooks" : [ ], "default_template" : "default", @@ -4913,12 +4911,12 @@ "apikey" : false, "blocked" : false, "id" : "bob", - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "admin" ] }, { "apikey" : true, "blocked" : false, "id" : "script", - "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "engineer" ] } ] } }, @@ -4956,7 +4954,7 @@ "example" : { "blocked" : false, "id" : "syncscript", - "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], + "roles" : [ "analyst" ], "secret" : "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH" } } @@ -5022,7 +5020,7 @@ "apikey" : true, "blocked" : false, "id" : "script", - "roles" : [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "engineer" ] } } }, @@ -5071,7 +5069,7 @@ "apikey" : false, "blocked" : false, "id" : "bob", - "roles" : [ "admin:backup:read", "admin:backup:restore", "admin:dashboard:write", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:settings:write", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:dashboard:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ] + "roles" : [ "analyst", "admin" ] } } }, diff --git a/generated/community.yml b/generated/community.yml index d062f13..1a0b321 100644 --- a/generated/community.yml +++ b/generated/community.yml @@ -1512,38 +1512,7 @@ paths: blocked: false id: bob roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - admin schema: $ref: '#/definitions/UserResponse' security: @@ -2422,39 +2391,6 @@ paths: icon: mdi-check id: clean name: Clean - roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write ticketTypes: - default_playbooks: [] default_template: default @@ -2543,39 +2479,6 @@ paths: icon: mdi-check id: clean name: Clean - roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write ticketTypes: - default_playbooks: [] default_template: default @@ -6948,62 +6851,12 @@ paths: blocked: false id: bob roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - admin - apikey: true blocked: false id: script roles: - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - engineer schema: items: $ref: '#/definitions/UserResponse' @@ -7037,21 +6890,7 @@ paths: blocked: false id: syncscript roles: - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read + - analyst secret: v39bOuobnlEljfWzjAgoKzhmnh1xSMxH schema: $ref: '#/definitions/NewUserResponse' @@ -7098,26 +6937,7 @@ paths: blocked: false id: script roles: - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - engineer schema: $ref: '#/definitions/UserResponse' security: @@ -7157,38 +6977,8 @@ paths: blocked: false id: bob roles: - - admin:backup:read - - admin:backup:restore - - admin:dashboard:write - - admin:group:write - - admin:job:read - - admin:job:write - - admin:log:read - - admin:settings:write - - admin:ticket:delete - - admin:user:write - - admin:userdata:read - - admin:userdata:write - - analyst:automation:read - - analyst:currentsettings:write - - analyst:currentuser:read - - analyst:currentuserdata:read - - analyst:dashboard:read - - analyst:file - - analyst:group:read - - analyst:playbook:read - - analyst:rule:read - - analyst:settings:read - - analyst:template:read - - analyst:ticket:read - - analyst:ticket:write - - analyst:tickettype:read - - analyst:user:read - - engineer:automation:write - - engineer:playbook:write - - engineer:rule:write - - engineer:template:write - - engineer:tickettype:write + - analyst + - admin schema: $ref: '#/definitions/UserResponse' security: diff --git a/go.cap b/go.cap deleted file mode 100644 index e60a979..0000000 --- a/go.cap +++ /dev/null @@ -1,122 +0,0 @@ -github.com/SecurityBrewery/catalyst/cmd/catalyst (network) - -github.com/RoaringBitmap/roaring (reflect, unsafe) -github.com/SecurityBrewery/catalyst (execute, file, network) -github.com/SecurityBrewery/catalyst/auth (network) -github.com/SecurityBrewery/catalyst/database/busdb (network) -github.com/SecurityBrewery/catalyst/generated/api (network) -github.com/SecurityBrewery/catalyst/index (file) -github.com/SecurityBrewery/catalyst/service (network) -github.com/alecthomas/kong (file, reflect, syscall, unsafe) -github.com/antlr/antlr4/runtime/Go/antlr (file, reflect) -github.com/arangodb/go-driver (file, network, reflect) -github.com/arangodb/go-driver/cluster (network) -github.com/arangodb/go-driver/http (file, network, reflect) -github.com/arangodb/go-velocypack (reflect) -github.com/aws/aws-sdk-go/aws (file, network) -github.com/aws/aws-sdk-go/aws/awsutil (reflect) -github.com/aws/aws-sdk-go/aws/client (file) -github.com/aws/aws-sdk-go/aws/corehandlers (file, network) -github.com/aws/aws-sdk-go/aws/credentials (file) -github.com/aws/aws-sdk-go/aws/credentials/processcreds (execute, file) -github.com/aws/aws-sdk-go/aws/credentials/ssocreds (file) -github.com/aws/aws-sdk-go/aws/credentials/stscreds (file) -github.com/aws/aws-sdk-go/aws/csm (network) -github.com/aws/aws-sdk-go/aws/defaults (file, network) -github.com/aws/aws-sdk-go/aws/ec2metadata (file, network) -github.com/aws/aws-sdk-go/aws/request (file, network, reflect) -github.com/aws/aws-sdk-go/aws/session (file, network) -github.com/aws/aws-sdk-go/aws/signer/v4 (file, network) -github.com/aws/aws-sdk-go/internal/ini (file) -github.com/aws/aws-sdk-go/internal/shareddefaults (file) -github.com/aws/aws-sdk-go/private/protocol (file, network, reflect) -github.com/aws/aws-sdk-go/private/protocol/json/jsonutil (reflect) -github.com/aws/aws-sdk-go/private/protocol/jsonrpc (file, network) -github.com/aws/aws-sdk-go/private/protocol/query/queryutil (reflect) -github.com/aws/aws-sdk-go/private/protocol/rest (file, network, reflect) -github.com/aws/aws-sdk-go/private/protocol/restjson (file, network) -github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil (reflect) -github.com/aws/aws-sdk-go/service/s3 (file, network) -github.com/aws/aws-sdk-go/service/s3/s3manager (network) -github.com/blevesearch/bleve/v2 (file, reflect) -github.com/blevesearch/bleve/v2/analysis (file) -github.com/blevesearch/bleve/v2/document (network, reflect) -github.com/blevesearch/bleve/v2/geo (reflect) -github.com/blevesearch/bleve/v2/index/scorch (file, reflect) -github.com/blevesearch/bleve/v2/index/upsidedown (reflect) -github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb (file) -github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap (file) -github.com/blevesearch/bleve/v2/mapping (file, network, reflect) -github.com/blevesearch/bleve/v2/search (reflect) -github.com/blevesearch/bleve/v2/search/collector (reflect) -github.com/blevesearch/bleve/v2/search/facet (reflect) -github.com/blevesearch/bleve/v2/search/highlight (reflect) -github.com/blevesearch/bleve/v2/search/query (file, network) -github.com/blevesearch/bleve/v2/search/scorer (reflect) -github.com/blevesearch/bleve/v2/search/searcher (network, reflect) -github.com/blevesearch/bleve/v2/size (reflect) -github.com/blevesearch/bleve_index_api (reflect) -github.com/blevesearch/mmap-go (file, reflect, unsafe) -github.com/blevesearch/vellum (file) -github.com/blevesearch/zapx/v11 (file, reflect, unsafe) -github.com/blevesearch/zapx/v12 (file, reflect, unsafe) -github.com/blevesearch/zapx/v13 (file, reflect, unsafe) -github.com/blevesearch/zapx/v14 (file, reflect, unsafe) -github.com/blevesearch/zapx/v15 (file, reflect, unsafe) -github.com/bmizerany/pat (network) -github.com/coreos/go-oidc/v3/oidc (file, network) -github.com/docker/distribution/registry/api/errcode (network) -github.com/docker/docker/api/types (file, network) -github.com/docker/docker/api/types/mount (file) -github.com/docker/docker/api/types/registry (network) -github.com/docker/docker/api/types/swarm (file) -github.com/docker/docker/client (file, network) -github.com/docker/docker/errdefs (network) -github.com/docker/go-connections/nat (network) -github.com/docker/go-connections/sockets (file, network, syscall) -github.com/docker/go-connections/tlsconfig (file) -github.com/go-chi/chi/v5 (network) -github.com/go-chi/chi/v5/middleware (file, network) -github.com/gobwas/ws (network, reflect, unsafe) -github.com/gobwas/ws/wsutil (file, network) -github.com/gogo/protobuf/proto (reflect, unsafe) -github.com/golang/protobuf/proto (file, reflect) -github.com/golang/protobuf/ptypes/any (reflect) -github.com/golang/protobuf/ptypes/duration (reflect) -github.com/golang/protobuf/ptypes/timestamp (reflect) -github.com/google/uuid (file, network) -github.com/imdario/mergo (reflect) -github.com/jmespath/go-jmespath (reflect) -github.com/sirupsen/logrus (file, reflect) -github.com/tus/tusd/pkg/handler (file, network) -github.com/tus/tusd/pkg/s3store (file, network) -github.com/xeipuuv/gojsonpointer (reflect) -github.com/xeipuuv/gojsonschema (file, network, reflect) -go.etcd.io/bbolt (file, reflect, syscall, unsafe) -golang.org/x/net/context/ctxhttp (network) -golang.org/x/net/internal/socks (network) -golang.org/x/net/proxy (file, network) -golang.org/x/oauth2 (network) -golang.org/x/oauth2/internal (file, network) -golang.org/x/sys/cpu (file) -golang.org/x/sys/internal/unsafeheader (unsafe) -golang.org/x/sys/unix (syscall, unsafe) -google.golang.org/genproto/googleapis/rpc/status (reflect) -google.golang.org/protobuf/internal/descfmt (reflect) -google.golang.org/protobuf/internal/detrand (file) -google.golang.org/protobuf/internal/encoding/tag (reflect) -google.golang.org/protobuf/internal/filedesc (reflect) -google.golang.org/protobuf/internal/filetype (reflect) -google.golang.org/protobuf/internal/impl (file, reflect, unsafe) -google.golang.org/protobuf/internal/strs (unsafe) -google.golang.org/protobuf/proto (reflect) -google.golang.org/protobuf/reflect/protoreflect (unsafe) -google.golang.org/protobuf/reflect/protoregistry (file) -google.golang.org/protobuf/types/descriptorpb (reflect) -google.golang.org/protobuf/types/known/anypb (reflect) -google.golang.org/protobuf/types/known/durationpb (reflect) -google.golang.org/protobuf/types/known/timestamppb (reflect) -gopkg.in/square/go-jose.v2 (reflect) -gopkg.in/square/go-jose.v2/json (reflect) -gopkg.in/yaml.v2 (reflect) -gopkg.in/yaml.v3 (reflect) diff --git a/go.mod b/go.mod index 7120c4b..fdc0d8a 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/SecurityBrewery/catalyst go 1.19 +replace github.com/xeipuuv/gojsonschema => github.com/warjiang/gojsonschema v1.2.1-0.20210329105853-aa9f9a8cfec7 + require ( github.com/alecthomas/kong v0.6.1 github.com/alecthomas/kong-yaml v0.1.1 @@ -14,18 +16,17 @@ require ( github.com/go-chi/chi/v5 v5.0.7 github.com/gobwas/ws v1.1.0 github.com/google/uuid v1.3.0 - github.com/gorilla/securecookie v1.1.1 github.com/iancoleman/strcase v0.2.0 github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 github.com/imdario/mergo v0.3.13 + github.com/jonas-plum/maut v0.0.0-20221001191853-1856efe6da0b github.com/mingrammer/commonregex v1.0.1 github.com/stretchr/testify v1.8.0 github.com/tidwall/gjson v1.14.3 github.com/tidwall/sjson v1.2.5 github.com/tus/tusd v1.9.2 github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be - golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 + golang.org/x/exp v0.0.0-20220929160808-de9c53c655b9 golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 gopkg.in/yaml.v3 v3.0.1 ) @@ -61,24 +62,24 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/securecookie v1.1.1 // indirect + github.com/gorilla/sessions v1.2.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/kr/pretty v0.3.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect - github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect go.etcd.io/bbolt v1.3.6 // indirect + golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect - golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220810155839-1856144b1d9c // indirect google.golang.org/grpc v1.49.0 // indirect @@ -87,5 +88,3 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools v2.2.0+incompatible // indirect ) - -replace github.com/xeipuuv/gojsonschema => github.com/warjiang/gojsonschema v1.2.1-0.20210329105853-aa9f9a8cfec7 diff --git a/go.sum b/go.sum index 1de9223..1cd2c3e 100644 --- a/go.sum +++ b/go.sum @@ -168,7 +168,6 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k= github.com/couchbase/moss v0.2.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -191,6 +190,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -305,10 +305,13 @@ github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/Oth github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= @@ -329,6 +332,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jonas-plum/maut v0.0.0-20221001191853-1856efe6da0b h1:gJtcxg/ifOIf7eWXv0ETHYUCEYLxo29WK7RKF+vJ/a4= +github.com/jonas-plum/maut v0.0.0-20221001191853-1856efe6da0b/go.mod h1:GHi17CboIfEAzcLKyOforrRGpNsJkIahosnrlgfsOvM= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -344,13 +349,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -379,7 +382,6 @@ github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3 github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -406,9 +408,6 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -417,8 +416,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -465,6 +464,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM= +github.com/zitadel/oidc v1.8.0 h1:FEUuAaZVgZv0dWGpCNcG1ov7COVDA5x2yzlYwqy8iTs= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -499,8 +500,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 h1:RjggHMcaTVp0LOVZcW0bo8alwHrOaCrGUDgfWUHhnN4= -golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20220929160808-de9c53c655b9 h1:lNtcVz/3bOstm7Vebox+5m3nLh/BYWnhmc3AhXOW6oI= +golang.org/x/exp v0.0.0-20220929160808-de9c53c655b9/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -687,8 +688,10 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/role/role.go b/role/role.go deleted file mode 100644 index 3a69de6..0000000 --- a/role/role.go +++ /dev/null @@ -1,171 +0,0 @@ -package role - -import ( - "errors" - "sort" - "strings" - - "golang.org/x/exp/slices" - - "github.com/SecurityBrewery/catalyst/generated/model" -) - -type Role string - -const ( - Analyst string = "analyst" - Engineer string = "engineer" - Admin string = "admin" - - AutomationRead Role = "analyst:automation:read" - CurrentuserRead Role = "analyst:currentuser:read" - CurrentuserdataRead Role = "analyst:currentuserdata:read" - CurrentuserdataWrite Role = "analyst:currentsettings:write" - DashboardRead Role = "analyst:dashboard:read" - FileReadWrite Role = "analyst:file" - GroupRead Role = "analyst:group:read" - PlaybookRead Role = "analyst:playbook:read" - RuleRead Role = "analyst:rule:read" - SettingsRead Role = "analyst:settings:read" - TemplateRead Role = "analyst:template:read" - TicketRead Role = "analyst:ticket:read" - TicketWrite Role = "analyst:ticket:write" - TickettypeRead Role = "analyst:tickettype:read" - UserRead Role = "analyst:user:read" - - AutomationWrite Role = "engineer:automation:write" - PlaybookWrite Role = "engineer:playbook:write" - RuleWrite Role = "engineer:rule:write" - TemplateWrite Role = "engineer:template:write" - TickettypeWrite Role = "engineer:tickettype:write" - - BackupRead Role = "admin:backup:read" - BackupRestore Role = "admin:backup:restore" - DashboardWrite Role = "admin:dashboard:write" - GroupWrite Role = "admin:group:write" - JobRead Role = "admin:job:read" - JobWrite Role = "admin:job:write" - LogRead Role = "admin:log:read" - SettingsWrite Role = "admin:settings:write" - TicketDelete Role = "admin:ticket:delete" - UserWrite Role = "admin:user:write" - UserdataRead Role = "admin:userdata:read" - UserdataWrite Role = "admin:userdata:write" -) - -func (p Role) String() string { - return string(p) -} - -func UserHasRoles(user *model.UserResponse, roles []Role) bool { - hasRoles := true - for _, role := range roles { - if !UserHasRole(user, role) { - hasRoles = false - - break - } - } - - return hasRoles -} - -func UserHasRole(user *model.UserResponse, role Role) bool { - return slices.Contains(FromStrings(user.Roles), role) -} - -func Explodes(s []string) []Role { - var roles []Role - for _, e := range s { - roles = append(roles, Explode(e)...) - } - sort.Slice(roles, func(i, j int) bool { - return roles[i].String() < roles[j].String() - }) - roles = slices.Compact(roles) - - return roles -} - -func Explode(s string) []Role { - var roles []Role - - switch s { - case Admin: - roles = append(roles, listPrefix(Admin)...) - - fallthrough - case Engineer: - roles = append(roles, listPrefix(Engineer)...) - - fallthrough - case Analyst: - roles = append(roles, listPrefix(Analyst)...) - - return roles - } - - for _, role := range List() { - if role.String() == s { - roles = append(roles, role) - } - } - - return roles -} - -func listPrefix(s string) []Role { - var roles []Role - - for _, role := range List() { - if strings.HasPrefix(role.String(), s+":") { - roles = append(roles, role) - } - } - - return roles -} - -func List() []Role { - return []Role{ - AutomationRead, CurrentuserdataRead, CurrentuserdataWrite, - CurrentuserRead, FileReadWrite, GroupRead, PlaybookRead, RuleRead, - UserdataRead, SettingsRead, TemplateRead, TicketRead, TickettypeRead, - TicketWrite, UserRead, AutomationWrite, PlaybookWrite, RuleWrite, - TemplateWrite, TickettypeWrite, BackupRead, BackupRestore, GroupWrite, - LogRead, UserdataWrite, TicketDelete, UserWrite, JobRead, JobWrite, - SettingsWrite, DashboardRead, DashboardWrite, - } -} - -func fromString(s string) (Role, error) { - for _, role := range List() { - if role.String() == s { - return role, nil - } - } - - return "", errors.New("unknown role") -} - -func Strings(roles []Role) []string { - var s []string - for _, role := range roles { - s = append(s, role.String()) - } - - return s -} - -func FromStrings(s []string) []Role { - var roles []Role - for _, e := range s { - role, err := fromString(e) - if err != nil { - continue - } - roles = append(roles, role) - } - - return roles -} diff --git a/roles.go b/roles.go new file mode 100644 index 0000000..4c99466 --- /dev/null +++ b/roles.go @@ -0,0 +1,50 @@ +package catalyst + +import maut "github.com/jonas-plum/maut/auth" + +var Admin = &maut.Role{ + Name: "admin", + Permissions: append(engineer.Permissions, + "backup:create", + "backup:restore", + "dashboard:write", + "job:read", + "job:write", + "log:read", + "settings:write", + "ticket:delete", + "tickettype:read", + "user:write", + "userdata:read", + "userdata:write", + ), +} + +var engineer = &maut.Role{ + Name: "engineer", + Permissions: append(analyst.Permissions, + "automation:write", + "playbook:write", + "template:write", + "tickettype:write", + ), +} + +var analyst = &maut.Role{ + Name: "analyst", + Permissions: []string{ + "automation:read", + "currentuser:read", + "currentuserdata:read", + "currentuserdata:write", + "dashboard:read", + "file:read", + "file:write", + "playbook:read", + "settings:read", + "template:read", + "ticket:read", + "ticket:write", + "user:read", + }, +} diff --git a/server.go b/server.go index 1513ba9..4c43e26 100644 --- a/server.go +++ b/server.go @@ -7,17 +7,14 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" + maut "github.com/jonas-plum/maut/auth" - "github.com/SecurityBrewery/catalyst/auth" "github.com/SecurityBrewery/catalyst/bus" "github.com/SecurityBrewery/catalyst/busservice" "github.com/SecurityBrewery/catalyst/database" - "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/index" - "github.com/SecurityBrewery/catalyst/role" "github.com/SecurityBrewery/catalyst/service" "github.com/SecurityBrewery/catalyst/storage" ) @@ -27,11 +24,9 @@ type Config struct { DB *database.Config Storage *storage.Config - Secret []byte - Auth *auth.Config + Auth *maut.Config ExternalAddress string InternalAddress string - InitialAPIKey string Network string Port int } @@ -49,12 +44,6 @@ func New(hooks *hooks.Hooks, config *Config) (*Server, error) { ctx, cancel := context.WithTimeout(ctx, time.Minute*10) defer cancel() - if config.Auth.OIDCAuthEnable { - if err := config.Auth.Load(ctx); err != nil { - return nil, err - } - } - catalystStorage, err := storage.New(config.Storage) if err != nil { return nil, err @@ -72,29 +61,19 @@ func New(hooks *hooks.Hooks, config *Config) (*Server, error) { return nil, err } - busservice.New(config.InternalAddress+"/api", config.InitialAPIKey, config.Network, catalystBus, catalystDatabase) + busservice.New(config.InternalAddress+"/api", config.Auth.InitialAPIKey, config.Network, catalystBus, catalystDatabase) catalystService, err := service.New(catalystBus, catalystDatabase, catalystStorage, GetVersion()) if err != nil { return nil, err } - if config.InitialAPIKey != "" { - _ = catalystDatabase.UserDelete(ctx, "setup") - - ctx = busdb.UserContext(ctx, &model.UserResponse{ - ID: "setup", - Roles: role.Strings(role.Explode(role.Admin)), - Apikey: false, - Blocked: false, - }) - _, err = catalystDatabase.UserCreateSetupAPIKey(ctx, config.InitialAPIKey) - if err != nil { - return nil, err - } + authenticator, err := maut.NewAuthenticator(ctx, config.Auth, newCatalystResolver(catalystDatabase)) + if err != nil { + return nil, err } - apiServer, err := setupAPI(catalystService, catalystStorage, catalystDatabase, config.DB, catalystBus, config) + apiServer, err := setupAPI(authenticator, catalystService, catalystStorage, catalystDatabase, config.DB, catalystBus, config) if err != nil { return nil, err } @@ -108,32 +87,22 @@ func New(hooks *hooks.Hooks, config *Config) (*Server, error) { }, nil } -func setupAPI(catalystService *service.Service, catalystStorage *storage.Storage, catalystDatabase *database.Database, dbConfig *database.Config, bus *bus.Bus, config *Config) (chi.Router, error) { - secureJar := auth.NewJar(config.Secret) - +func setupAPI(authenticator *maut.Authenticator, catalystService *service.Service, catalystStorage *storage.Storage, catalystDatabase *database.Database, dbConfig *database.Config, bus *bus.Bus, config *Config) (chi.Router, error) { middlewares := []func(next http.Handler) http.Handler{ - auth.Authenticate(catalystDatabase, config.Auth, secureJar), - auth.AuthorizeBlockedUser(), + authenticator.Authenticate(), + authenticator.AuthorizeBlockedUser(), } // create server - apiServer := api.NewServer(catalystService, auth.AuthorizeRole, middlewares...) - fileReadWrite := auth.AuthorizeRole([]string{role.FileReadWrite.String()}) - tudHandler := tusdUpload(catalystDatabase, bus, catalystStorage.S3(), config.ExternalAddress) - apiServer.With(fileReadWrite).Head("/files/{ticketID}/tusd/{id}", tudHandler) - apiServer.With(fileReadWrite).Patch("/files/{ticketID}/tusd/{id}", tudHandler) - apiServer.With(fileReadWrite).Post("/files/{ticketID}/tusd", tudHandler) - apiServer.With(fileReadWrite).Post("/files/{ticketID}/upload", upload(catalystDatabase, catalystStorage.S3(), catalystStorage.Uploader())) - apiServer.With(fileReadWrite).Get("/files/{ticketID}/download/{key}", download(catalystStorage.Downloader())) - - apiServer.With(auth.AuthorizeRole([]string{role.BackupRead.String()})).Get("/backup/create", backupHandler(catalystStorage, dbConfig)) - apiServer.With(auth.AuthorizeRole([]string{role.BackupRestore.String()})).Post("/backup/restore", restoreHandler(catalystStorage, catalystDatabase, dbConfig)) + apiServer := api.NewServer(catalystService, permissionAuth(authenticator), middlewares...) + apiServer.Mount("/files", fileServer(authenticator, catalystDatabase, bus, catalystStorage, config)) + apiServer.Mount("/backup", backupServer(authenticator, catalystStorage, catalystDatabase, dbConfig)) server := chi.NewRouter() server.Use(middleware.RequestID, middleware.RealIP, middleware.Logger, middleware.Recoverer) server.Mount("/api", apiServer) + server.Mount("/auth", authenticator.Server()) server.With(middlewares...).Handle("/wss", handleWebSocket(bus)) - server.Mount("/auth", auth.Server(config.Auth, catalystDatabase, secureJar)) server.Get("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/ui/", http.StatusFound) @@ -141,3 +110,31 @@ func setupAPI(catalystService *service.Service, catalystStorage *storage.Storage return server, nil } + +func permissionAuth(authenticator *maut.Authenticator) func([]string) func(http.Handler) http.Handler { + return func(strings []string) func(http.Handler) http.Handler { + return authenticator.AuthorizePermission(strings...) + } +} + +func fileServer(authenticator *maut.Authenticator, catalystDatabase *database.Database, bus *bus.Bus, catalystStorage *storage.Storage, config *Config) *chi.Mux { + fileRW := authenticator.AuthorizePermission("file:read", "file:write") // TODO: add test + tudHandler := tusdUpload(catalystDatabase, bus, catalystStorage.S3(), config.ExternalAddress) + server := chi.NewRouter() + server.With(fileRW).Head("/{ticketID}/tusd/{id}", tudHandler) + server.With(fileRW).Patch("/{ticketID}/tusd/{id}", tudHandler) + server.With(fileRW).Post("/{ticketID}/tusd", tudHandler) + server.With(fileRW).Post("/{ticketID}/upload", upload(catalystDatabase, catalystStorage.S3(), catalystStorage.Uploader())) + server.With(fileRW).Get("/{ticketID}/download/{key}", download(catalystStorage.Downloader())) + + return server +} + +func backupServer(authenticator *maut.Authenticator, catalystStorage *storage.Storage, catalystDatabase *database.Database, dbConfig *database.Config) *chi.Mux { + server := chi.NewRouter() + // TODO: add test + server.With(authenticator.AuthorizePermission("backup:create")).Get("/create", backupHandler(catalystStorage, dbConfig)) + server.With(authenticator.AuthorizePermission("backup:restore")).Post("/restore", restoreHandler(catalystStorage, catalystDatabase, dbConfig)) + + return server +} diff --git a/service/service.go b/service/service.go index bc7e82a..ea3ce76 100644 --- a/service/service.go +++ b/service/service.go @@ -4,10 +4,10 @@ import ( "context" "github.com/arangodb/go-driver" + maut "github.com/jonas-plum/maut/auth" "github.com/SecurityBrewery/catalyst/bus" "github.com/SecurityBrewery/catalyst/database" - "github.com/SecurityBrewery/catalyst/database/busdb" "github.com/SecurityBrewery/catalyst/storage" ) @@ -28,7 +28,7 @@ func (s *Service) publishRequest(ctx context.Context, err error, function string } if ids != nil { userID := "unknown" - user, ok := busdb.UserFromContext(ctx) + user, _, ok := maut.UserFromContext(ctx) if ok { userID = user.ID } diff --git a/service/settings.go b/service/settings.go index ee3d82a..e401525 100644 --- a/service/settings.go +++ b/service/settings.go @@ -3,11 +3,10 @@ package service import ( "context" "errors" - "sort" - "github.com/SecurityBrewery/catalyst/database/busdb" + maut "github.com/jonas-plum/maut/auth" + "github.com/SecurityBrewery/catalyst/generated/model" - "github.com/SecurityBrewery/catalyst/role" ) func (s *Service) GetSettings(ctx context.Context) (*model.SettingsResponse, error) { @@ -29,7 +28,7 @@ func (s *Service) SaveSettings(ctx context.Context, settings *model.Settings) (* } func (s *Service) settings(ctx context.Context, globalSettings *model.Settings) (*model.SettingsResponse, error) { - user, ok := busdb.UserFromContext(ctx) + user, permissions, ok := maut.UserFromContext(ctx) if !ok { return nil, errors.New("no user in context") } @@ -47,13 +46,11 @@ func (s *Service) settings(ctx context.Context, globalSettings *model.Settings) if userData.Timeformat != nil { globalSettings.Timeformat = *userData.Timeformat } - roles := role.Strings(role.List()) - sort.Strings(roles) return &model.SettingsResponse{ Tier: model.SettingsResponseTierCommunity, Version: s.version, - Roles: roles, + Roles: permissions, TicketTypes: ticketTypeList, ArtifactStates: globalSettings.ArtifactStates, ArtifactKinds: globalSettings.ArtifactKinds, diff --git a/service/user.go b/service/user.go index 5ff7f3d..32d80c4 100644 --- a/service/user.go +++ b/service/user.go @@ -6,9 +6,9 @@ import ( "fmt" "github.com/arangodb/go-driver" + maut "github.com/jonas-plum/maut/auth" "github.com/SecurityBrewery/catalyst/database" - "github.com/SecurityBrewery/catalyst/database/busdb" "github.com/SecurityBrewery/catalyst/generated/model" ) @@ -59,11 +59,16 @@ func (s *Service) DeleteUser(ctx context.Context, s2 string) (err error) { } func (s *Service) CurrentUser(ctx context.Context) (*model.UserResponse, error) { - user, ok := busdb.UserFromContext(ctx) + user, _, ok := maut.UserFromContext(ctx) if !ok { return nil, errors.New("no user in context") } - s.publishRequest(ctx, nil, "CurrentUser", userResponseID(user)) + s.publishRequest(ctx, nil, "CurrentUser", userID(user.ID)) - return user, nil + return &model.UserResponse{ + ID: user.ID, + Apikey: user.APIKey, + Blocked: user.Blocked, + Roles: user.Roles, + }, nil } diff --git a/service/userdata.go b/service/userdata.go index 9b80b66..c4e2b8d 100644 --- a/service/userdata.go +++ b/service/userdata.go @@ -6,9 +6,9 @@ import ( "fmt" "github.com/arangodb/go-driver" + maut "github.com/jonas-plum/maut/auth" "github.com/SecurityBrewery/catalyst/database" - "github.com/SecurityBrewery/catalyst/database/busdb" "github.com/SecurityBrewery/catalyst/generated/model" ) @@ -39,7 +39,7 @@ func (s *Service) UpdateUserData(ctx context.Context, id string, data *model.Use } func (s *Service) CurrentUserData(ctx context.Context) (doc *model.UserDataResponse, err error) { - user, ok := busdb.UserFromContext(ctx) + user, _, ok := maut.UserFromContext(ctx) if !ok { return nil, errors.New("no user in context") } @@ -48,7 +48,7 @@ func (s *Service) CurrentUserData(ctx context.Context) (doc *model.UserDataRespo } func (s *Service) UpdateCurrentUserData(ctx context.Context, data *model.UserData) (doc *model.UserDataResponse, err error) { - user, ok := busdb.UserFromContext(ctx) + user, _, ok := maut.UserFromContext(ctx) if !ok { return nil, errors.New("no user in context") } diff --git a/test/data.go b/test/data.go index eb04a7b..6a5fafb 100644 --- a/test/data.go +++ b/test/data.go @@ -4,6 +4,8 @@ import ( "context" "time" + maut "github.com/jonas-plum/maut/auth" + "github.com/SecurityBrewery/catalyst/database" "github.com/SecurityBrewery/catalyst/database/migrations" "github.com/SecurityBrewery/catalyst/generated/model" @@ -13,7 +15,7 @@ import ( var ( bobSetting = &model.UserData{Email: pointer.String("bob@example.org"), Name: pointer.String("Bob Bad")} bobForm = &model.UserForm{ID: "bob", Blocked: false, Roles: []string{"admin"}} - Bob = &model.UserResponse{ID: "bob", Blocked: false, Roles: []string{"admin"}} + Bob = &maut.User{ID: "bob", Blocked: false, Roles: []string{"admin"}} ) func SetupTestData(ctx context.Context, db *database.Database) error { diff --git a/test/test.go b/test/test.go index 93cd543..8f901c0 100644 --- a/test/test.go +++ b/test/test.go @@ -12,13 +12,12 @@ import ( "github.com/arangodb/go-driver" "github.com/coreos/go-oidc/v3/oidc" "github.com/go-chi/chi/v5" + maut "github.com/jonas-plum/maut/auth" "golang.org/x/oauth2" "github.com/SecurityBrewery/catalyst" - "github.com/SecurityBrewery/catalyst/auth" "github.com/SecurityBrewery/catalyst/bus" "github.com/SecurityBrewery/catalyst/database" - "github.com/SecurityBrewery/catalyst/database/busdb" "github.com/SecurityBrewery/catalyst/generated/api" "github.com/SecurityBrewery/catalyst/generated/model" "github.com/SecurityBrewery/catalyst/hooks" @@ -28,14 +27,13 @@ import ( ) func Context() context.Context { - return busdb.UserContext(context.Background(), Bob) + return maut.UserContext(context.Background(), Bob, nil) // TODO add permissions ? } func Config(ctx context.Context) (*catalyst.Config, error) { config := &catalyst.Config{ - InitialAPIKey: "test", - IndexPath: "index.bleve", - Network: "catalyst", + IndexPath: "index.bleve", + Network: "catalyst", DB: &database.Config{ Host: "http://localhost:8529", User: "root", @@ -46,8 +44,9 @@ func Config(ctx context.Context) (*catalyst.Config, error) { User: "minio", Password: "minio123", }, - Secret: []byte("4ef5b29539b70233dd40c02a1799d25079595565e05a193b09da2c3e60ada1cd"), - Auth: &auth.Config{ + Auth: &maut.Config{ + InitialAPIKey: "test", + CookieSecret: []byte("4ef5b29539b70233dd40c02a1799d25079595565e05a193b09da2c3e60ada1cd"), SimpleAuthEnable: true, APIKeyAuthEnable: true, OIDCAuthEnable: true, @@ -66,10 +65,6 @@ func Config(ctx context.Context) (*catalyst.Config, error) { }, } - if err := config.Auth.Load(ctx); err != nil { - return nil, err - } - return config, nil } @@ -176,7 +171,7 @@ func Server(t *testing.T) (context.Context, *catalyst.Config, *bus.Bus, *index.I catalystServer := api.NewServer(catalystService, func(s []string) func(http.Handler) http.Handler { return func(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handler.ServeHTTP(w, busdb.SetContext(r, Bob)) + handler.ServeHTTP(w, r.WithContext(maut.UserContext(r.Context(), Bob, nil))) }) } }) diff --git a/ui/cypress/e2e/catalyst.cy.js b/ui/cypress/e2e/catalyst.cy.js index b23703e..ac99952 100644 --- a/ui/cypress/e2e/catalyst.cy.js +++ b/ui/cypress/e2e/catalyst.cy.js @@ -3,7 +3,7 @@ beforeEach(() => { cy.login(); - cy.getCookie('user').should('exist'); + cy.getCookie('maut_user').should('exist'); cy.intercept('GET', '/api/userdata/demo', { fixture: 'userdata_demo.json' }) cy.intercept('GET', '/api/users/demo', { fixture: 'user_demo.json' }) diff --git a/ui/cypress/fixtures/user_demo.json b/ui/cypress/fixtures/user_demo.json index 5bd89cf..e08d96b 100644 --- a/ui/cypress/fixtures/user_demo.json +++ b/ui/cypress/fixtures/user_demo.json @@ -2,38 +2,5 @@ "apikey": false, "blocked": false, "id": "demo", - "roles": [ - "admin:backup:read", - "admin:backup:restore", - "admin:dashboard:write", - "admin:group:write", - "admin:job:read", - "admin:job:write", - "admin:log:read", - "admin:settings:write", - "admin:ticket:delete", - "admin:user:write", - "admin:userdata:read", - "admin:userdata:write", - "analyst:automation:read", - "analyst:currentsettings:write", - "analyst:currentuser:read", - "analyst:currentuserdata:read", - "analyst:dashboard:read", - "analyst:file", - "analyst:group:read", - "analyst:playbook:read", - "analyst:rule:read", - "analyst:settings:read", - "analyst:template:read", - "analyst:ticket:read", - "analyst:ticket:write", - "analyst:tickettype:read", - "analyst:user:read", - "engineer:automation:write", - "engineer:playbook:write", - "engineer:rule:write", - "engineer:template:write", - "engineer:tickettype:write" - ] + "roles": [ "admin" ] } \ No newline at end of file diff --git a/ui/src/App.vue b/ui/src/App.vue index 3ef635e..18a6c23 100644 --- a/ui/src/App.vue +++ b/ui/src/App.vue @@ -5,7 +5,7 @@
- +
Catalyst Login @@ -45,7 +45,7 @@ - + @@ -208,16 +208,16 @@ export default Vue.extend({ valid: true, authenticated: false, settings: [ - { icon: "mdi-format-list-bulleted-type", name: "Ticket Types", to: "TicketTypeList", role: "engineer:tickettype:write" }, - { icon: "mdi-file-hidden", name: "Templates", to: "TemplateList", role: "analyst:template:read" }, - { icon: "mdi-file-cog-outline", name: "Playbooks", to: "PlaybookList", role: "analyst:playbook:read" }, - { icon: "mdi-flash", name: "Automations", to: "AutomationList", role: "analyst:automation:read" }, - { icon: "mdi-filter", name: "Ingestion Rules", to: "RuleList", role: "analyst:rule:read", tier: "enterprise" }, - { icon: "mdi-account", name: "Users & API Keys", to: "UserList", role: "admin:user:write" }, - { icon: "mdi-account-group", name: "Groups", to: "GroupList", role: "admin:group:write", tier: "enterprise" }, - { icon: "mdi-cogs", name: "User Data", to: "UserDataList", role: "admin:userdata:write" }, - { icon: "mdi-format-list-checks", name: "Jobs", to: "JobList", role: "admin:job:write" }, - { icon: "mdi-cog", name: "Settings", to: "Settings", role: "admin:settings:write" }, + { icon: "mdi-format-list-bulleted-type", name: "Ticket Types", to: "TicketTypeList", role: "tickettype:write" }, + { icon: "mdi-file-hidden", name: "Templates", to: "TemplateList", role: "template:read" }, + { icon: "mdi-file-cog-outline", name: "Playbooks", to: "PlaybookList", role: "playbook:read" }, + { icon: "mdi-flash", name: "Automations", to: "AutomationList", role: "automation:read" }, + { icon: "mdi-filter", name: "Ingestion Rules", to: "RuleList", role: "rule:read", tier: "enterprise" }, + { icon: "mdi-account", name: "Users & API Keys", to: "UserList", role: "user:write" }, + { icon: "mdi-account-group", name: "Groups", to: "GroupList", role: "group:write", tier: "enterprise" }, + { icon: "mdi-cogs", name: "User Data", to: "UserDataList", role: "userdata:write" }, + { icon: "mdi-format-list-checks", name: "Jobs", to: "JobList", role: "job:write" }, + { icon: "mdi-cog", name: "Settings", to: "Settings", role: "settings:write" }, ], mini: true, goto: "", @@ -235,7 +235,7 @@ export default Vue.extend({ }, internal: function (): Array { return [ - { icon: "mdi-view-dashboard", name: "Dashboards", to: "DashboardList", role: "analyst:dashboard:read" }, + { icon: "mdi-view-dashboard", name: "Dashboards", to: "DashboardList", role: "dashboard:read" }, { icon: "mdi-check-bold", name: "Open Tasks", to: "TaskList", count: this.$store.state.task_count }, ] }, @@ -280,8 +280,8 @@ export default Vue.extend({ this.$router.push({ name: "TicketList", params: { type: type } }); }, hasRole: function (s: string) { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; }, diff --git a/ui/src/components/AdvancedJSONSchemaEditor.vue b/ui/src/components/AdvancedJSONSchemaEditor.vue index 4841dea..41f07df 100644 --- a/ui/src/components/AdvancedJSONSchemaEditor.vue +++ b/ui/src/components/AdvancedJSONSchemaEditor.vue @@ -151,8 +151,8 @@ export default Vue.extend({ return DateTime.fromISO(s).toFormat(format); }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; } diff --git a/ui/src/components/AppLink.vue b/ui/src/components/AppLink.vue index 7734e12..c6a75a9 100644 --- a/ui/src/components/AppLink.vue +++ b/ui/src/components/AppLink.vue @@ -41,8 +41,8 @@ export default Vue.extend({ return true; } let has = false; - if (this.$store.state.user.roles) { - this.lodash.forEach(this.$store.state.user.roles, (userRole) => { + if (this.$store.state.settings.roles) { + this.lodash.forEach(this.$store.state.settings.roles, (userRole) => { if (link.role === userRole || this.lodash.startsWith(link.role, userRole + ":")) { has = true; } diff --git a/ui/src/components/List.vue b/ui/src/components/List.vue index 4bfe36c..296e67d 100644 --- a/ui/src/components/List.vue +++ b/ui/src/components/List.vue @@ -119,8 +119,8 @@ export default Vue.extend({ this.dialog = false; }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; } diff --git a/ui/src/views/Automation.vue b/ui/src/views/Automation.vue index 937fa26..7aa785f 100644 --- a/ui/src/views/Automation.vue +++ b/ui/src/views/Automation.vue @@ -72,7 +72,7 @@ export default Vue.extend({ }, computed: { readonly: function (): boolean { - return !this.hasRole("engineer:automation:write"); + return !this.hasRole("automation:write"); }, types: function (): Array { return [ AutomationResponseTypeEnum.Global, AutomationResponseTypeEnum.Playbook, AutomationResponseTypeEnum.Artifact ] @@ -104,8 +104,8 @@ export default Vue.extend({ } }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; }, diff --git a/ui/src/views/AutomationList.vue b/ui/src/views/AutomationList.vue index ad81ca4..03be702 100644 --- a/ui/src/views/AutomationList.vue +++ b/ui/src/views/AutomationList.vue @@ -7,7 +7,7 @@ itemname="id" singular="Automation" plural="Automations" - writepermission="engineer:automation:write" + writepermission="automation:write" @delete="deleteAutomation" > diff --git a/ui/src/views/DashboardList.vue b/ui/src/views/DashboardList.vue index bf7a913..6dfbe0c 100644 --- a/ui/src/views/DashboardList.vue +++ b/ui/src/views/DashboardList.vue @@ -7,7 +7,7 @@ itemname="name" singular="Dashboard" plural="Dashboards" - writepermission="admin:dashboard:write" + writepermission="dashboard:write" @delete="deleteDashboard" > diff --git a/ui/src/views/Job.vue b/ui/src/views/Job.vue index a5471fe..3c8dd69 100644 --- a/ui/src/views/Job.vue +++ b/ui/src/views/Job.vue @@ -94,7 +94,7 @@ export default Vue.extend({ }, computed: { readonly: function (): boolean { - return !this.hasRole("admin:job:write"); + return !this.hasRole("job:write"); }, globalautomations: function (): Array { if (!this.automations) { @@ -157,8 +157,8 @@ export default Vue.extend({ }); }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; } diff --git a/ui/src/views/JobList.vue b/ui/src/views/JobList.vue index bb1185f..ea65320 100644 --- a/ui/src/views/JobList.vue +++ b/ui/src/views/JobList.vue @@ -68,7 +68,7 @@ export default Vue.extend({ }), computed: { canWrite: function (): boolean { - return this.hasRole("admin:job:write"); + return this.hasRole("job:write"); }, }, methods: { @@ -80,8 +80,8 @@ export default Vue.extend({ }); }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; } diff --git a/ui/src/views/Playbook.vue b/ui/src/views/Playbook.vue index 0b39694..e5f2a3f 100644 --- a/ui/src/views/Playbook.vue +++ b/ui/src/views/Playbook.vue @@ -174,7 +174,7 @@ export default Vue.extend({ } }, readonly: function (): boolean { - return !this.hasRole("engineer:playbook:write"); + return !this.hasRole("playbook:write"); }, }, methods: { @@ -286,8 +286,8 @@ export default Vue.extend({ } }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; } diff --git a/ui/src/views/PlaybookList.vue b/ui/src/views/PlaybookList.vue index d6e394a..e237295 100644 --- a/ui/src/views/PlaybookList.vue +++ b/ui/src/views/PlaybookList.vue @@ -8,7 +8,7 @@ singular="Playbook" plural="Playbooks" @delete="deletePlaybook" - writepermission="engineer:playbook:write" + writepermission="playbook:write" > diff --git a/ui/src/views/Template.vue b/ui/src/views/Template.vue index 5ddca15..084f285 100644 --- a/ui/src/views/Template.vue +++ b/ui/src/views/Template.vue @@ -47,7 +47,7 @@ export default Vue.extend({ }, computed: { readonly: function (): boolean { - return !this.hasRole("engineer:template:write"); + return !this.hasRole("template:write"); }, }, methods: { @@ -81,8 +81,8 @@ export default Vue.extend({ } }, hasRole: function (s: string): boolean { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; } diff --git a/ui/src/views/TemplateList.vue b/ui/src/views/TemplateList.vue index fe46cd6..c5ee9e1 100644 --- a/ui/src/views/TemplateList.vue +++ b/ui/src/views/TemplateList.vue @@ -7,7 +7,7 @@ itemname="name" singular="Template" plural="Templates" - writepermission="engineer:template:write" + writepermission="template:write" @delete="deleteTemplate" > diff --git a/ui/src/views/Ticket.vue b/ui/src/views/Ticket.vue index eae9d14..289425d 100644 --- a/ui/src/views/Ticket.vue +++ b/ui/src/views/Ticket.vue @@ -761,7 +761,7 @@
Files - + mdi-plus
@@ -1017,8 +1017,8 @@ export default Vue.extend({ }, methods: { hasRole: function (s: string) { - if (this.$store.state.user.roles) { - return this.lodash.includes(this.$store.state.user.roles, s); + if (this.$store.state.settings.roles) { + return this.lodash.includes(this.$store.state.settings.roles, s); } return false; }, diff --git a/ui/src/views/TicketTypeList.vue b/ui/src/views/TicketTypeList.vue index d01f23a..865fdd3 100644 --- a/ui/src/views/TicketTypeList.vue +++ b/ui/src/views/TicketTypeList.vue @@ -8,7 +8,7 @@ singular="Ticket Type" plural="Ticket Types" @delete="deleteTicketType" - writepermission="engineer:tickettype:write" + writepermission="tickettype:write" > diff --git a/ui/src/views/UserDataList.vue b/ui/src/views/UserDataList.vue index c04d4aa..8844d63 100644 --- a/ui/src/views/UserDataList.vue +++ b/ui/src/views/UserDataList.vue @@ -9,7 +9,7 @@ plural="User Data" :show-new="false" :deletable="false" - writepermission="admin:userdata:write" + writepermission="userdata:write" > diff --git a/ui/src/views/UserList.vue b/ui/src/views/UserList.vue index 72a30df..41fa138 100644 --- a/ui/src/views/UserList.vue +++ b/ui/src/views/UserList.vue @@ -8,7 +8,7 @@ singular="User / API Key" plural="Users / API Keys" @delete="deleteUser" - writepermission="admin:user:write" + writepermission="user:write" >