Skip to content

Commit

Permalink
Bootstrap application + add initial support for object types
Browse files Browse the repository at this point in the history
  • Loading branch information
kkajla12 committed Feb 16, 2023
0 parents commit 435317b
Show file tree
Hide file tree
Showing 23 changed files with 2,981 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
warrant.yaml
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Warrant
35 changes: 35 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module github.com/warrant-dev/warrant

go 1.19

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.11.2 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ngrok/sqlmw v0.0.0-20220520173518-97c9c04efc79 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rs/xid v1.4.0 // indirect
github.com/rs/zerolog v1.29.0 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.15.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
504 changes: 504 additions & 0 deletions go.sum

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions server/cmd/warrant/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"fmt"
"net/http"

"github.com/rs/zerolog/log"
objecttype "github.com/warrant-dev/warrant/server/pkg/authz/objecttype"
"github.com/warrant-dev/warrant/server/pkg/database"
"github.com/warrant-dev/warrant/server/pkg/service"
)

type ServiceEnv struct {
Database database.Database
}

func (env *ServiceEnv) DB() database.Database {
return env.Database
}

func NewServiceEnv(database database.Database) ServiceEnv {
return ServiceEnv{
Database: database,
}
}

func main() {
config := service.NewConfig()
database, err := initDb(config)
if err != nil {
log.Fatal().Err(err).Msg("Could not initialize and connect to the configured database. Shutting down.")
}

svcEnv := NewServiceEnv(database)
svcs := []service.Service{
objecttype.NewObjectTypeService(&svcEnv),
}

routes := make([]service.Route, 0)
for _, svc := range svcs {
routes = append(routes, svc.GetRoutes()...)
}

log.Info().Msgf("Listening on port %d", config.Port)
shutdownErr := http.ListenAndServe(fmt.Sprintf(":%d", config.Port), service.NewRouter(&config, "", routes))
log.Fatal().Err(shutdownErr).Msg("")
}

func initDb(config service.Config) (database.Database, error) {
if config.Database.MySQL != nil {
db := database.NewMySQL(*config.Database.MySQL)
return db, db.Connect()
}

return nil, fmt.Errorf("invalid database configuration provided")
}
Binary file added server/cmd/warrant/warrant
Binary file not shown.
124 changes: 124 additions & 0 deletions server/pkg/authz/objecttype/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package authz

import (
"net/http"

"github.com/gorilla/mux"
"github.com/warrant-dev/warrant/server/pkg/middleware"
"github.com/warrant-dev/warrant/server/pkg/service"
)

// GetRoutes registers all route handlers for this module
func (svc ObjectTypeService) GetRoutes() []service.Route {
return []service.Route{
// create
{
Pattern: "/v1/object-types",
Method: "POST",
Handler: service.NewRouteHandler(svc.Env(), create),
},

// get
{
Pattern: "/v1/object-types",
Method: "GET",
Handler: middleware.ChainMiddleware(
service.NewRouteHandler(svc.Env(), list),
middleware.ListMiddleware[ObjectTypeListParamParser],
),
},

// list
{
Pattern: "/v1/object-types/{type}",
Method: "GET",
Handler: service.NewRouteHandler(svc.Env(), getByTypeId),
},

// update
{
Pattern: "/v1/object-types/{type}",
Method: "POST",
Handler: service.NewRouteHandler(svc.Env(), update),
},
{
Pattern: "/v1/object-types/{type}",
Method: "PUT",
Handler: service.NewRouteHandler(svc.Env(), update),
},

// delete
{
Pattern: "/v1/object-types/{type}",
Method: "DELETE",
Handler: service.NewRouteHandler(svc.Env(), delete),
},
}
}

func create(env service.Env, w http.ResponseWriter, r *http.Request) error {
var objectTypeSpec ObjectTypeSpec
err := service.ParseJSONBody(r.Body, &objectTypeSpec)
if err != nil {
return err
}

createdObjectTypeSpec, err := NewObjectTypeService(env).Create(objectTypeSpec)
if err != nil {
return err
}

service.SendJSONResponse(w, createdObjectTypeSpec)
return nil
}

func list(env service.Env, w http.ResponseWriter, r *http.Request) error {
listParams := middleware.GetListParamsFromContext(r.Context())
objectTypeSpecs, err := NewObjectTypeService(env).List(listParams)
if err != nil {
return err
}

service.SendJSONResponse(w, objectTypeSpecs)
return nil
}

func getByTypeId(env service.Env, w http.ResponseWriter, r *http.Request) error {
typeParam := mux.Vars(r)["type"]
objectTypeSpec, err := NewObjectTypeService(env).GetByTypeId(typeParam)
if err != nil {
return err
}

service.SendJSONResponse(w, objectTypeSpec)
return nil
}

func update(env service.Env, w http.ResponseWriter, r *http.Request) error {
var objectTypeSpec ObjectTypeSpec
err := service.ParseJSONBody(r.Body, &objectTypeSpec)
if err != nil {
return err
}

typeParam := mux.Vars(r)["type"]
updatedObjectTypeSpec, err := NewObjectTypeService(env).UpdateByTypeId(typeParam, objectTypeSpec)
if err != nil {
return err
}

service.SendJSONResponse(w, updatedObjectTypeSpec)
return nil
}

func delete(env service.Env, w http.ResponseWriter, r *http.Request) error {
typeId := mux.Vars(r)["type"]
err := NewObjectTypeService(env).DeleteByTypeId(typeId)
if err != nil {
return err
}

w.Header().Set("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
return nil
}
36 changes: 36 additions & 0 deletions server/pkg/authz/objecttype/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package authz

import (
"fmt"
"time"
)

type ObjectTypeListParamParser struct{}

func (parser ObjectTypeListParamParser) GetDefaultSortBy() string {
return "objectType"
}

func (parser ObjectTypeListParamParser) GetSupportedSortBys() []string {
return []string{"createdAt", "objectType"}
}

func (parser ObjectTypeListParamParser) ParseValue(val string, sortBy string) (interface{}, error) {
switch sortBy {
case "createdAt":
afterValue, err := time.Parse(time.RFC3339, val)
if err != nil || afterValue.Equal(time.Time{}) {
return nil, fmt.Errorf("must be a valid time in the %s", time.RFC3339)
}

return afterValue, nil
case "objectType":
if val == "" {
return nil, fmt.Errorf("must not be empty")
}

return val, nil
default:
return nil, fmt.Errorf("must match type of selected sortBy attribute %s", sortBy)
}
}
28 changes: 28 additions & 0 deletions server/pkg/authz/objecttype/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package authz

import (
"encoding/json"
"time"

"github.com/warrant-dev/warrant/server/pkg/database"
)

// ObjectType model
type ObjectType struct {
ID int64 `json:"-" db:"id"`
TypeId string `json:"typeId" db:"typeId"`
Definition string `json:"definition" db:"definition"`
CreatedAt time.Time `json:"-" db:"createdAt"`
UpdatedAt time.Time `json:"-" db:"updatedAt"`
DeletedAt database.NullTime `json:"-" db:"deletedAt"`
}

func (objectType ObjectType) ToObjectTypeSpec() (*ObjectTypeSpec, error) {
var objectTypeSpec ObjectTypeSpec
err := json.Unmarshal([]byte(objectType.Definition), &objectTypeSpec)
if err != nil {
return nil, err
}

return &objectTypeSpec, nil
}
Loading

0 comments on commit 435317b

Please sign in to comment.