Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Internal Feature] Transaction Log Txlog Initial Development #93

Merged
merged 25 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
513dfe2
Added TxLogs Schema and Data Model
TanmoySG Mar 30, 2023
0c9adf1
Updated gen-txlog-models in Makefile
TanmoySG Mar 30, 2023
c7a4e44
go mod tidy
TanmoySG Mar 30, 2023
ff133da
fix filename
TanmoySG Mar 30, 2023
72d6ad1
update txLogs model and schema (#89)
TanmoySG Apr 1, 2023
a59b599
added txlogs methods #89
TanmoySG Apr 1, 2023
f08ecb1
upgrade version for insecure package
TanmoySG Apr 1, 2023
7ee5dc4
update model Http Status code type to int
TanmoySG Apr 1, 2023
7c6df9e
Added Privilege types - read/write/wildcard
TanmoySG Apr 1, 2023
248c4b5
added `IsTxnLoggable` method to determine if txn is loggable based on…
TanmoySG Apr 1, 2023
37641de
Added handler for transactions (#89)
TanmoySG Apr 2, 2023
496c656
added HandleTransaction for all route handlers
TanmoySG Apr 2, 2023
0bbb444
refactor genEntityType
TanmoySG Apr 2, 2023
693fc99
added check to txLog only successful requests
TanmoySG Apr 2, 2023
2151b70
updated handler transaction to use txnActor
TanmoySG Apr 2, 2023
7a67e7a
added dotTxLog file handler
TanmoySG Apr 3, 2023
3c5ae16
using log-commit pattern in HandleTransaction
TanmoySG Apr 3, 2023
5799b12
move HandleTransactions on wdbHandler, renamed to wh.handleTransactions
TanmoySG Apr 3, 2023
6604e72
added tx basepath for wdb
TanmoySG Apr 3, 2023
967561b
sendResponse and validateRequest made private funcs
TanmoySG Apr 3, 2023
a337908
Added Root Directory Path as config
TanmoySG Apr 3, 2023
751ee71
use wdbBasePath for wdbTxLogs
TanmoySG Apr 3, 2023
81c7606
cleanup
TanmoySG Apr 3, 2023
b166bbe
added txLog base dir and file creation
TanmoySG Apr 3, 2023
a53ae08
fixed filepath formats
TanmoySG Apr 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ build-cli:
go build -o bin/wdbctl ./cmd/wdbctl/cli.go

run:
go run ./cmd/wunderdb/wdb.go
go run ./cmd/wunderdb/wdb.go

gen-txlog-models:
gojsonschema -p txlModel internal/txlogs/model/txlog.schema.json -o internal/txlogs/model/model.go

instal-dev:
go get github.com/atombender/go-jsonschema/...
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.3.8 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -103,12 +105,16 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
2 changes: 2 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
)

type Config struct {
RootDirectoryPath string `json:"ROOT_DIR_PATH"`
AdminID string `json:"ADMIN_ID"`
AdminPassword string `json:"-"`
Port string `json:"PORT"`
Expand Down Expand Up @@ -69,6 +70,7 @@ func Load() (*Config, error) {
}

c := &Config{
RootDirectoryPath: wdbRootDirectory,
AdminID: configMap.getValue(ADMIN_ID, override),
AdminPassword: configMap.getValue(ADMIN_PASSWORD, override),
Port: configMap.getValue(PORT, override),
Expand Down
1 change: 1 addition & 0 deletions internal/config/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const (
PORT = "PORT"
PERSISTANT_STORAGE_PATH = "PERSISTANT_STORAGE_PATH"
OVERRIDE_CONFIG = "OVERRIDE_CONFIG"
ROOT_DIR_PATH = "ROOT_DIR_PATH"
)

var defaultValues = map[string]string{
Expand Down
23 changes: 18 additions & 5 deletions internal/privileges/constants.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
package privileges

// Scope of Privilege Type
// TODO: Use for below Privileges (ref. L14-21)
type PrivilegeScopeType string

const (
UserPrivileges = "userPrivilege"
GlobalPrivileges = "globalPrivilege"
DatabasePrivileges = "databasePrivilege"
CollectionPrivileges = "collectionPrivilege"
)

// Read, Write, Wildcard Action Type
type PrivilegeActionType string

var (
WildcardPrivilege PrivilegeActionType = "wildcardPrivilege"
WritePrivilege PrivilegeActionType = "writePrivilege"
ReadPrivilege PrivilegeActionType = "readPrivilege"
)

const (
Allowed = true
Denied = false
)

const (
Wildcard = "*"
)
Expand Down Expand Up @@ -37,8 +55,3 @@ const (
UpdateData = "updateData"
DeleteData = "deleteData"
)

const (
Allowed = true
Denied = false
)
77 changes: 56 additions & 21 deletions internal/privileges/privileges.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,53 @@
package privileges

var (
PrivilegeScope = map[string]string{
CreateRole: GlobalPrivileges,
CreateDatabase: GlobalPrivileges,
LoginUser: GlobalPrivileges,
ListRole: GlobalPrivileges,
GrantRole: UserPrivileges,
UpdateRole: UserPrivileges,
ReadDatabase: DatabasePrivileges,
UpdateDatabase: DatabasePrivileges,
DeleteDatabase: DatabasePrivileges,
CreateCollection: DatabasePrivileges,
ReadCollection: CollectionPrivileges,
UpdateCollection: CollectionPrivileges,
DeleteCollection: CollectionPrivileges,
AddData: CollectionPrivileges,
ReadData: CollectionPrivileges,
UpdateData: CollectionPrivileges,
DeleteData: CollectionPrivileges,
}
)
// TODO: merge PrivilegeScope and PrivilegeType maps
// into on map/struct and use same everywhere, eg:
//
// map[string]struct{
// Scope PrivilegeScopeType
// Type PrivilegeActionType
// }
var PrivilegeScope = map[string]string{
CreateRole: GlobalPrivileges,
CreateDatabase: GlobalPrivileges,
LoginUser: GlobalPrivileges,
ListRole: GlobalPrivileges,
GrantRole: UserPrivileges,
UpdateRole: UserPrivileges,
ReadDatabase: DatabasePrivileges,
UpdateDatabase: DatabasePrivileges,
DeleteDatabase: DatabasePrivileges,
CreateCollection: DatabasePrivileges,
ReadCollection: CollectionPrivileges,
UpdateCollection: CollectionPrivileges,
DeleteCollection: CollectionPrivileges,
AddData: CollectionPrivileges,
ReadData: CollectionPrivileges,
UpdateData: CollectionPrivileges,
DeleteData: CollectionPrivileges,
}

var PrivilegeType = map[string]PrivilegeActionType{
CreateRole: WildcardPrivilege,
LoginUser: WildcardPrivilege,
GrantRole: WildcardPrivilege,
UpdateRole: WildcardPrivilege,
ListRole: WildcardPrivilege,

ReadDatabase: ReadPrivilege,
ReadCollection: ReadPrivilege,
ReadData: ReadPrivilege,

CreateDatabase: WritePrivilege,
UpdateDatabase: WritePrivilege,
DeleteDatabase: WritePrivilege,
CreateCollection: WritePrivilege,
UpdateCollection: WritePrivilege,
DeleteCollection: WritePrivilege,
AddData: WritePrivilege,
UpdateData: WritePrivilege,
DeleteData: WritePrivilege,
}

func IsAvailable(privilege string) bool {
_, privilegeExists := PrivilegeScope[privilege]
Expand All @@ -33,3 +60,11 @@ func Category(privilege string) string {
}
return ""
}

func GetPrivilegeType(privilege string) PrivilegeActionType {
privilegeType, ok := PrivilegeType[privilege]
if ok {
return privilegeType
}
return WildcardPrivilege
}
35 changes: 30 additions & 5 deletions internal/server/handlers/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ func (wh wdbHandlers) CreateCollection(c *fiber.Ctx) error {
}

entities := model.Entities{
Databases: &databaseName,
Databases: &databaseName,
Collections: &collection.Name, // check
}

if err := ValidateRequest(collection); err != nil {
if err := validateRequest(collection); err != nil {
apiError = err
} else {
isValid, error := wh.handleAuthenticationAndAuthorization(c, entities, privilege)
Expand All @@ -42,7 +43,15 @@ func (wh wdbHandlers) CreateCollection(c *fiber.Ctx) error {

resp := response.Format(privilege, apiError, nil)

return SendResponse(c, resp.Marshal(), resp.HttpStatusCode)
if err := sendResponse(c, resp); err != nil {
return err
}

if err := wh.handleTransactions(c, resp, entities); err != nil {
return err
}

return nil
}

func (wh wdbHandlers) FetchCollection(c *fiber.Ctx) error {
Expand All @@ -68,7 +77,15 @@ func (wh wdbHandlers) FetchCollection(c *fiber.Ctx) error {

resp := response.Format(privilege, apiError, fetchedDatabase)

return SendResponse(c, resp.Marshal(), resp.HttpStatusCode)
if err := sendResponse(c, resp); err != nil {
return err
}

if err := wh.handleTransactions(c, resp, entities); err != nil {
return err
}

return nil
}

func (wh wdbHandlers) DeleteCollection(c *fiber.Ctx) error {
Expand All @@ -93,5 +110,13 @@ func (wh wdbHandlers) DeleteCollection(c *fiber.Ctx) error {

resp := response.Format(privilege, apiError, nil)

return SendResponse(c, resp.Marshal(), resp.HttpStatusCode)
if err := sendResponse(c, resp); err != nil {
return err
}

if err := wh.handleTransactions(c, resp, entities); err != nil {
return err
}

return nil
}
64 changes: 56 additions & 8 deletions internal/server/handlers/common.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
package handlers

import (
"github.com/TanmoySG/wunderDB/internal/server/response"
"github.com/TanmoySG/wunderDB/internal/txlogs"
txlModel "github.com/TanmoySG/wunderDB/internal/txlogs/model"
"github.com/TanmoySG/wunderDB/internal/users/authentication"
"github.com/TanmoySG/wunderDB/model"
er "github.com/TanmoySG/wunderDB/pkg/wdb/errors"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
)

var (
noEntities = model.Entities{}
)

const (
AuthorizationHeader = "Authorization"

authSuccessful = true
authFailure = false
)

var (
noEntities = model.Entities{}
)

func (wh wdbHandlers) handleAuthenticationAndAuthorization(c *fiber.Ctx, entities model.Entities, privilege string) (bool, *er.WdbError) {

username, isValidUser, error := wh.handleAuthentication(c)
Expand Down Expand Up @@ -65,13 +70,24 @@ func (wh wdbHandlers) handleAuthorization(username string, entity model.Entities
return authSuccessful, nil
}

func SendResponse(c *fiber.Ctx, marshaledResponse []byte, statusCode int) error {
func sendResponse(c *fiber.Ctx, apiResponse response.ApiResponse) error {
c.Set(ContentType, ApplicationJson)
c.Send(marshaledResponse)
return c.SendStatus(statusCode)

marshaledResponse := apiResponse.Marshal()
err := c.Send(marshaledResponse)
if err != nil {
return err
}

err = c.SendStatus(apiResponse.HttpStatusCode)
if err != nil {
return err
}

return nil
}

func ValidateRequest(request any) *er.WdbError {
func validateRequest(request any) *er.WdbError {
validate := validator.New()

err := validate.Struct(request)
Expand All @@ -80,3 +96,35 @@ func ValidateRequest(request any) *er.WdbError {
}
return nil
}

func (wh wdbHandlers) handleTransactions(c *fiber.Ctx, apiResponse response.ApiResponse, entities model.Entities) error {
if txlogs.IsTxnLoggable(apiResponse.Response.Action) {
if apiResponse.Response.Status == response.StatusSuccess {
databaseEntity := *entities.Databases
if entities.Databases == nil {
databaseEntity = ""
}

txnActor := txlogs.GetTxnActor(c.Get(AuthorizationHeader))
txnAction := apiResponse.Response.Action

txnHttpDetails := txlogs.GetTxnHttpDetails(*c)
txnEntityPath := txlModel.TxlogSchemaJsonEntityPath{
Database: databaseEntity,
Collection: entities.Collections,
}

txnLog := txlogs.CreateTxLog(txnAction, txnActor, apiResponse.Response.Status, txnEntityPath, txnHttpDetails)

err := wh.wdbTxLogs.Log(txnLog)
if err != nil {
return err
}
err = wh.wdbTxLogs.Commit()
if err != nil {
return err
}
}
}
return nil
}
Loading