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

Backend [Unit Test] db/config.go UserHasManageBountyRoles, UserHasAccess, CheckUser, & RolesCheck #1605

Merged
merged 2 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 15 additions & 5 deletions db/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@ import (
)

type database struct {
db *gorm.DB
db *gorm.DB
getOrganizationByUuid func(uuid string) Organization
getUserRoles func(uuid string, pubkey string) []UserRoles
}

func NewDatabaseConfig(db *gorm.DB) *database {
return &database{
db: db,
getOrganizationByUuid: DB.GetOrganizationByUuid,
getUserRoles: DB.GetUserRoles,
}
}

// DB is the object
Expand Down Expand Up @@ -264,10 +274,10 @@ func UserHasAccess(pubKeyFromAuth string, uuid string, role string) bool {
}

func (db database) UserHasAccess(pubKeyFromAuth string, uuid string, role string) bool {
org := DB.GetOrganizationByUuid(uuid)
org := db.getOrganizationByUuid(uuid)
var hasRole bool = false
if pubKeyFromAuth != org.OwnerPubKey {
userRoles := DB.GetUserRoles(uuid, pubKeyFromAuth)
userRoles := db.getUserRoles(uuid, pubKeyFromAuth)
hasRole = RolesCheck(userRoles, role)
return hasRole
}
Expand All @@ -276,9 +286,9 @@ func (db database) UserHasAccess(pubKeyFromAuth string, uuid string, role string

func (db database) UserHasManageBountyRoles(pubKeyFromAuth string, uuid string) bool {
var manageRolesCount = len(ManageBountiesGroup)
org := DB.GetOrganizationByUuid(uuid)
org := db.getOrganizationByUuid(uuid)
if pubKeyFromAuth != org.OwnerPubKey {
userRoles := DB.GetUserRoles(uuid, pubKeyFromAuth)
userRoles := db.getUserRoles(uuid, pubKeyFromAuth)

for _, role := range ManageBountiesGroup {
// check for the manage bounty roles
Expand Down
154 changes: 154 additions & 0 deletions db/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package db

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"gorm.io/gorm"
)

func TestRolesCheck_UserHasRole(t *testing.T) {
// Mock user roles
userRoles := []UserRoles{
{Role: "ADD BOUNTY", OwnerPubKey: "user1", OrgUuid: "org1", Created: &time.Time{}},
}

// Role to check
roleToCheck := "ADD BOUNTY"

// Call the function
result := RolesCheck(userRoles, roleToCheck)

// Assert that it returns true
if !result {
t.Errorf("Expected RolesCheck to return true for user with role %s, got false", roleToCheck)
}
}

func TestRolesCheck_UserDoesNotHaveRole(t *testing.T) {
// Mock user roles
userRoles := []UserRoles{
{Role: "DELETE BOUNTY", OwnerPubKey: "user2", OrgUuid: "org1", Created: &time.Time{}},
}

// Role to check
roleToCheck := "ADD BOUNTY"

// Call the function
result := RolesCheck(userRoles, roleToCheck)

// Assert that it returns false
if result {
t.Errorf("Expected RolesCheck to return false for user without role %s, got true", roleToCheck)
}
}

func TestCheckUser(t *testing.T) {
userRoles := []UserRoles{
{OwnerPubKey: "userPublicKey"},
}

// if in the user roles, one of the owner_pubkey belongs to the user return true else return false
assert.True(t, CheckUser(userRoles, "userPublicKey"))
assert.False(t, CheckUser(userRoles, "anotherPublicKey"))
}

func TestUserHasAccess(t *testing.T) {
mockGetOrganizationByUuid := func(uuid string) Organization {
return Organization{
Uuid: uuid,
OwnerPubKey: "org_admin",
}
}

mockGetUserRoles := func(uuid string, pubkey string) []UserRoles {
return []UserRoles{
{Role: "ADD BOUNTY", OwnerPubKey: pubkey, OrgUuid: uuid, Created: &time.Time{}},
}
}

mockDB := &gorm.DB{}

databaseConfig := NewDatabaseConfig(mockDB)
databaseConfig.getOrganizationByUuid = mockGetOrganizationByUuid
databaseConfig.getUserRoles = mockGetUserRoles

t.Run("Should test that if the user is the admin of an organization returns true", func(t *testing.T) {
result := databaseConfig.UserHasAccess("org_admin", "org_uuid", "ADD BOUNTY")

// Assert that it returns true since the user is the org admin
if !result {
t.Errorf("Expected UserHasAccess to return true for organization admin, got false")
}
})

t.Run("Should test that if the user is not the organization admin, and the user has the required role it should return true", func(t *testing.T) {
result := databaseConfig.UserHasAccess("user_pubkey", "org_uuid", "ADD BOUNTY")

// Assert that it returns true since the user has the required role
if !result {
t.Errorf("Expected UserHasAccess to return true for user with required role, got false")
}
})

t.Run("Should test that if the user is not the organization admin, and the user has not the required role it should return false", func(t *testing.T) {
result := databaseConfig.UserHasAccess("user_pubkey", "org_uuid", "DELETE BOUNTY")

// Assert that it returns false since the user does not have the required role
if result {
t.Errorf("Expected UserHasAccess to return false for user without required role, got true")
}
})
}

func TestUserHasManageBountyRoles(t *testing.T) {
mockGetOrganizationByUuid := func(uuid string) Organization {
return Organization{
Uuid: uuid,
OwnerPubKey: "org_admin",
}
}

mockGetUserRoles := func(uuid string, pubkey string) []UserRoles {
if uuid == "org_uuid" {
return []UserRoles{
{Role: "ADD BOUNTY", OwnerPubKey: pubkey, OrgUuid: uuid, Created: &time.Time{}},
}
} else {
return []UserRoles{
{Role: "ADD BOUNTY", OwnerPubKey: pubkey, OrgUuid: uuid, Created: &time.Time{}},
{Role: "UPDATE BOUNTY", OwnerPubKey: pubkey, OrgUuid: uuid, Created: &time.Time{}},
{Role: "DELETE BOUNTY", OwnerPubKey: pubkey, OrgUuid: uuid, Created: &time.Time{}},
{Role: "PAY BOUNTY", OwnerPubKey: pubkey, OrgUuid: uuid, Created: &time.Time{}},
}
}
}

mockDB := &gorm.DB{}

databaseConfig := NewDatabaseConfig(mockDB)
databaseConfig.getOrganizationByUuid = mockGetOrganizationByUuid
databaseConfig.getUserRoles = mockGetUserRoles

t.Run("Should test that if the user is the organization admin return true", func(t *testing.T) {
result := databaseConfig.UserHasManageBountyRoles("org_admin", "org_uuid")

// Assert that it returns true since the user is the org admin
assert.True(t, result, "Expected UserHasManageBountyRoles to return true for organization admin")
})

t.Run("Should test that if the user has all bounty roles return true", func(t *testing.T) {
result := databaseConfig.UserHasManageBountyRoles("user_pubkey", "org_uuid2")

// Assert that it returns true since the user has all bounty roles
assert.True(t, result, "Expected UserHasManageBountyRoles to return true for user with all bounty roles")
})

t.Run("Should test that if the user don't have all bounty roles return false.", func(t *testing.T) {
result := databaseConfig.UserHasManageBountyRoles("user_pubkey", "org_uuid")

// Assert that it returns false since the user does not have all bounty roles
assert.False(t, result, "Expected UserHasManageBountyRoles to return false for user without all bounty roles")
})
}
26 changes: 16 additions & 10 deletions handlers/bounty.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,27 @@ import (
"github.com/stakwork/sphinx-tribes/config"
"github.com/stakwork/sphinx-tribes/db"
"github.com/stakwork/sphinx-tribes/utils"
"gorm.io/gorm"
)

type bountyHandler struct {
httpClient HttpClient
db db.Database
getSocketConnections func(host string) (db.Client, error)
generateBountyResponse func(bounties []db.Bounty) []db.BountyResponse
httpClient HttpClient
db db.Database
getSocketConnections func(host string) (db.Client, error)
generateBountyResponse func(bounties []db.Bounty) []db.BountyResponse
userHasAccess func(pubKeyFromAuth string, uuid string, role string) bool
userHasManageBountyRoles func(pubKeyFromAuth string, uuid string) bool
}

func NewBountyHandler(httpClient HttpClient, database db.Database) *bountyHandler {
dbConf := db.NewDatabaseConfig(&gorm.DB{})
return &bountyHandler{

httpClient: httpClient,
db: database,
getSocketConnections: db.Store.GetSocketConnections,
httpClient: httpClient,
db: database,
getSocketConnections: db.Store.GetSocketConnections,
userHasAccess: dbConf.UserHasAccess,
userHasManageBountyRoles: dbConf.UserHasManageBountyRoles,
}
}

Expand Down Expand Up @@ -239,7 +245,7 @@ func (h *bountyHandler) CreateOrEditBounty(w http.ResponseWriter, r *http.Reques
// check if bounty belongs to user
if pubKeyFromAuth != dbBounty.OwnerID {
if bounty.OrgUuid != "" {
hasBountyRoles := h.db.UserHasManageBountyRoles(pubKeyFromAuth, bounty.OrgUuid)
hasBountyRoles := h.userHasManageBountyRoles(pubKeyFromAuth, bounty.OrgUuid)
if !hasBountyRoles {
msg := "You don't have a=the right permission ton update bounty"
fmt.Println(msg)
Expand Down Expand Up @@ -448,7 +454,7 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request

// check if user is the admin of the organization
// or has a pay bounty role
hasRole := h.db.UserHasAccess(pubKeyFromAuth, bounty.OrgUuid, db.PayBounty)
hasRole := h.userHasAccess(pubKeyFromAuth, bounty.OrgUuid, db.PayBounty)
if !hasRole {
w.WriteHeader(http.StatusUnauthorized)
json.NewEncoder(w).Encode("You don't have appropriate permissions to pay bounties")
Expand Down Expand Up @@ -567,7 +573,7 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ

// check if user is the admin of the organization
// or has a withdraw bounty budget role
hasRole := h.db.UserHasAccess(pubKeyFromAuth, request.OrgUuid, db.WithdrawBudget)
hasRole := h.userHasAccess(pubKeyFromAuth, request.OrgUuid, db.WithdrawBudget)
if !hasRole {
w.WriteHeader(http.StatusUnauthorized)
errMsg := formatPayError("You don't have appropriate permissions to withdraw bounty budget")
Expand Down
Loading
Loading