diff --git a/db/config.go b/db/config.go index cdece0150..99128fbb2 100644 --- a/db/config.go +++ b/db/config.go @@ -10,6 +10,16 @@ import ( "gorm.io/gorm" ) +type configHandler struct { + db Database +} + +func NewConfigHandler(database Database) *configHandler { + return &configHandler{ + db: database, + } +} + type database struct { db *gorm.DB getWorkspaceByUuid func(uuid string) Workspace @@ -389,6 +399,38 @@ func (db database) UserHasAccess(pubKeyFromAuth string, uuid string, role string return true } +func (ch configHandler) UserHasAccess(pubKeyFromAuth string, uuid string, role string) bool { + org := ch.db.GetWorkspaceByUuid(uuid) + var hasRole bool = false + if pubKeyFromAuth != org.OwnerPubKey { + userRoles := ch.db.GetUserRoles(uuid, pubKeyFromAuth) + hasRole = RolesCheck(userRoles, role) + return hasRole + } + return true +} + +func (ch configHandler) UserHasManageBountyRoles(pubKeyFromAuth string, uuid string) bool { + var manageRolesCount = len(ManageBountiesGroup) + org := ch.db.GetWorkspaceByUuid(uuid) + if pubKeyFromAuth != org.OwnerPubKey { + userRoles := ch.db.GetUserRoles(uuid, pubKeyFromAuth) + + for _, role := range ManageBountiesGroup { + // check for the manage bounty roles + hasRole := RolesCheck(userRoles, role) + if hasRole { + manageRolesCount-- + } + } + + if manageRolesCount != 0 { + return false + } + } + return true +} + func (db database) UserHasManageBountyRoles(pubKeyFromAuth string, uuid string) bool { var manageRolesCount = len(ManageBountiesGroup) org := db.getWorkspaceByUuid(uuid) diff --git a/db/workspaces.go b/db/workspaces.go index 8e3f1ea92..896203ab2 100644 --- a/db/workspaces.go +++ b/db/workspaces.go @@ -58,6 +58,14 @@ func (db database) CreateOrEditWorkspace(m Workspace) (Workspace, error) { return m, nil } +func (db database) DeleteWorkspace() (bool, error) { + result := db.db.Exec("DELETE FROM workspaces") + if result.Error != nil { + return false, result.Error + } + return true, nil +} + func (db database) CreateOrEditWorkspaceRepository(m WorkspaceRepositories) (WorkspaceRepositories, error) { m.Name = strings.TrimSpace(m.Name) m.Url = strings.TrimSpace(m.Url) diff --git a/handlers/workspaces.go b/handlers/workspaces.go index faae40a5d..c53336901 100644 --- a/handlers/workspaces.go +++ b/handlers/workspaces.go @@ -17,22 +17,27 @@ import ( ) type workspaceHandler struct { - db db.Database - generateBountyHandler func(bounties []db.NewBounty) []db.BountyResponse - getLightningInvoice func(payment_request string) (db.InvoiceResult, db.InvoiceError) - userHasAccess func(pubKeyFromAuth string, uuid string, role string) bool - userHasManageBountyRoles func(pubKeyFromAuth string, uuid string) bool + db db.Database + generateBountyHandler func(bounties []db.NewBounty) []db.BountyResponse + getLightningInvoice func(payment_request string) (db.InvoiceResult, db.InvoiceError) + userHasAccess func(pubKeyFromAuth string, uuid string, role string) bool + configUserHasAccess func(pubKeyFromAuth string, uuid string, role string) bool + configUserHasManageBountyRoles func(pubKeyFromAuth string, uuid string) bool + userHasManageBountyRoles func(pubKeyFromAuth string, uuid string) bool } func NewWorkspaceHandler(database db.Database) *workspaceHandler { bHandler := NewBountyHandler(http.DefaultClient, database) dbConf := db.NewDatabaseConfig(&gorm.DB{}) + configHandler := db.NewConfigHandler(database) return &workspaceHandler{ - db: database, - generateBountyHandler: bHandler.GenerateBountyResponse, - getLightningInvoice: bHandler.GetLightningInvoice, - userHasAccess: dbConf.UserHasAccess, - userHasManageBountyRoles: dbConf.UserHasManageBountyRoles, + db: database, + generateBountyHandler: bHandler.GenerateBountyResponse, + getLightningInvoice: bHandler.GetLightningInvoice, + userHasAccess: dbConf.UserHasAccess, + configUserHasAccess: configHandler.UserHasAccess, + configUserHasManageBountyRoles: configHandler.UserHasManageBountyRoles, + userHasManageBountyRoles: dbConf.UserHasManageBountyRoles, } } @@ -482,23 +487,23 @@ func (oh *workspaceHandler) GetUserDropdownWorkspaces(w http.ResponseWriter, r * return } - user := db.DB.GetPerson(userId) + user := oh.db.GetPerson(userId) // get the workspaces created by the user, then get all the workspaces // the user has been added to, loop through to get the workspace - workspaces := GetCreatedWorkspaces(user.OwnerPubKey) - assignedWorkspaces := db.DB.GetUserAssignedWorkspaces(user.OwnerPubKey) + workspaces := oh.GetCreatedWorkspaces(user.OwnerPubKey) + assignedWorkspaces := oh.db.GetUserAssignedWorkspaces(user.OwnerPubKey) for _, value := range assignedWorkspaces { uuid := value.WorkspaceUuid - workspace := db.DB.GetWorkspaceByUuid(uuid) - bountyCount := db.DB.GetWorkspaceBountyCount(uuid) - hasRole := db.UserHasAccess(user.OwnerPubKey, uuid, db.ViewReport) - hasBountyRoles := oh.userHasManageBountyRoles(user.OwnerPubKey, uuid) + workspace := oh.db.GetWorkspaceByUuid(uuid) + bountyCount := oh.db.GetWorkspaceBountyCount(uuid) + hasRole := oh.configUserHasAccess(user.OwnerPubKey, uuid, db.ViewReport) + hasBountyRoles := oh.configUserHasManageBountyRoles(user.OwnerPubKey, uuid) // don't add deleted workspaces to the list if !workspace.Deleted && hasBountyRoles { if hasRole { - budget := db.DB.GetWorkspaceBudget(uuid) + budget := oh.db.GetWorkspaceBudget(uuid) workspace.Budget = budget.TotalBudget } else { workspace.Budget = 0 @@ -531,6 +536,25 @@ func GetCreatedWorkspaces(pubkey string) []db.Workspace { return workspaces } +func (oh *workspaceHandler) GetCreatedWorkspaces(pubkey string) []db.Workspace { + workspaces := oh.db.GetUserCreatedWorkspaces(pubkey) + // add bounty count to the workspace + for index, value := range workspaces { + uuid := value.Uuid + bountyCount := oh.db.GetWorkspaceBountyCount(uuid) + hasRole := oh.configUserHasAccess(pubkey, uuid, db.ViewReport) + + if hasRole { + budget := oh.db.GetWorkspaceBudget(uuid) + workspaces[index].Budget = budget.TotalBudget + } else { + workspaces[index].Budget = 0 + } + workspaces[index].BountyCount = bountyCount + } + return workspaces +} + func (oh *workspaceHandler) GetWorkspaceBounties(w http.ResponseWriter, r *http.Request) { uuid := chi.URLParam(r, "uuid") diff --git a/handlers/workspaces_test.go b/handlers/workspaces_test.go index f9c9ea753..ae9a057a6 100644 --- a/handlers/workspaces_test.go +++ b/handlers/workspaces_test.go @@ -8,6 +8,7 @@ import ( "math/rand" "net/http" "net/http/httptest" + "strconv" "strings" "testing" "time" @@ -1200,7 +1201,100 @@ func TestGetWorkspaceUsers(t *testing.T) { } func TestGetUserDropdownWorkspaces(t *testing.T) { + teardownSuite := SetupSuite(t) + defer teardownSuite(t) + + oHandler := NewWorkspaceHandler(db.TestDB) + + db.TestDB.DeleteWorkspace() + person := db.Person{ + Uuid: "uuid", + OwnerAlias: "alias", + UniqueName: "unique_name", + OwnerPubKey: "pubkey", + PriceToMeet: 0, + Description: "description", + } + + person2 := db.Person{ + Uuid: "uuid2", + OwnerAlias: "alias2", + UniqueName: "unique_name2", + OwnerPubKey: "pubkey2", + PriceToMeet: 0, + Description: "description2", + } + db.TestDB.CreateOrEditPerson(person) + db.TestDB.CreateOrEditPerson(person2) + + workspace := db.Workspace{ + Uuid: "workspace_uuid", + Name: "workspace_name", + OwnerPubKey: "person.OwnerPubkey", + Github: "gtihub", + Website: "website", + Description: "description", + } + db.TestDB.CreateOrEditWorkspace(workspace) + + roles := []db.WorkspaceUserRoles{ + db.WorkspaceUserRoles{ + WorkspaceUuid: workspace.Uuid, + OwnerPubKey: person2.OwnerPubKey, + Role: "ADD BOUNTY", + }, + db.WorkspaceUserRoles{ + WorkspaceUuid: workspace.Uuid, + OwnerPubKey: person2.OwnerPubKey, + Role: "UPDATE BOUNTY", + }, + db.WorkspaceUserRoles{ + WorkspaceUuid: workspace.Uuid, + OwnerPubKey: person2.OwnerPubKey, + Role: "DELETE BOUNTY", + }, + db.WorkspaceUserRoles{ + WorkspaceUuid: workspace.Uuid, + OwnerPubKey: person2.OwnerPubKey, + Role: "PAY BOUNTY", + }, + } + + db.TestDB.CreateUserRoles(roles, workspace.Uuid, person2.OwnerPubKey) + + dbPerson := db.TestDB.GetPersonByUuid(person2.Uuid) + + ctx := context.WithValue(context.Background(), auth.ContextKey, workspace.OwnerPubKey) + + t.Run("should return user dropdown workspaces", func(t *testing.T) { + rr := httptest.NewRecorder() + rctx := chi.NewRouteContext() + rctx.URLParams.Add("userId", strconv.Itoa(int(dbPerson.ID))) + req, err := http.NewRequestWithContext(context.WithValue(ctx, chi.RouteCtxKey, rctx), http.MethodGet, "/user/dropdown/"+strconv.Itoa(int(dbPerson.ID)), nil) + if err != nil { + t.Fatal(err) + } + + handler := http.HandlerFunc(oHandler.GetUserDropdownWorkspaces) + handler.ServeHTTP(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code) + + var responseWorkspaces []db.Workspace + err = json.Unmarshal(rr.Body.Bytes(), &responseWorkspaces) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, responseWorkspaces) + assert.Equal(t, workspace.Uuid, responseWorkspaces[0].Uuid) + assert.Equal(t, workspace.Name, responseWorkspaces[0].Name) + assert.Equal(t, workspace.OwnerPubKey, responseWorkspaces[0].OwnerPubKey) + assert.Equal(t, workspace.Github, responseWorkspaces[0].Github) + assert.Equal(t, workspace.Website, responseWorkspaces[0].Website) + assert.Equal(t, workspace.Description, responseWorkspaces[0].Description) + }) } func TestCreateOrEditWorkspaceRepository(t *testing.T) {