From 78b82ab1c241ae3cbee7e83ee92371d1558d74b7 Mon Sep 17 00:00:00 2001 From: aryan Date: Sun, 17 Mar 2024 12:19:40 +0530 Subject: [PATCH 01/19] Modified db schema of Owner. Signed-off-by: aryan --- chaoscenter/authentication/pkg/entities/project.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chaoscenter/authentication/pkg/entities/project.go b/chaoscenter/authentication/pkg/entities/project.go index 3dda69124d5..b632aeb740b 100644 --- a/chaoscenter/authentication/pkg/entities/project.go +++ b/chaoscenter/authentication/pkg/entities/project.go @@ -12,7 +12,11 @@ type Project struct { type Owner struct { UserID string `bson:"user_id" json:"userID"` Username string `bson:"username" json:"username"` + Invitation Invitation `bson:"invitation" json:"invitation"` + JoinedAt int64 `bson:"joined_at" json:"joinedAt"` + DeactivatedAt *int64 `bson:"deactivated_at,omitempty" json:"deactivatedAt,omitempty"` } + type MemberStat struct { Owner *[]Owner `bson:"owner" json:"owner"` Total int `bson:"total" json:"total"` From 962175b5e30a05d14a6fef334d8cf377e5e134ee Mon Sep 17 00:00:00 2001 From: aryan Date: Sun, 17 Mar 2024 12:24:57 +0530 Subject: [PATCH 02/19] Added new API GetProjectOwners. Signed-off-by: aryan --- .../api/handlers/rest/project_handler.go | 24 +++++++++++++++++++ .../api/routes/project_router.go | 1 + .../authentication/pkg/entities/project.go | 4 ++-- .../authentication/pkg/project/repository.go | 23 ++++++++++++++++++ .../pkg/services/project_service.go | 5 ++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index 731f1d926b7..2754bd3307e 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -195,6 +195,30 @@ func GetActiveProjectMembers(service services.ApplicationService) gin.HandlerFun } } +// GetActiveProjectOwners godoc +// +// @Summary Get active project Owners. +// @Description Return list of active project owners. +// @Tags ProjectRouter +// @Param state path string true "State" +// @Accept json +// @Produce json +// @Failure 500 {object} response.ErrServerError +// @Success 200 {object} response.Response{} +// @Router /get_project_owners/:project_id/:state [get] +func GetActiveProjectOwners(service services.ApplicationService) gin.HandlerFunc { + return func(c *gin.Context) { + projectID := c.Param("project_id") + // state := c.Param("state") + owners, err := service.GetProjectOwners(projectID) + if err != nil { + c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) + return + } + c.JSON(http.StatusOK, gin.H{"data": owners}) + } +} + // getInvitation returns the Invitation status func getInvitation(service services.ApplicationService, member entities.MemberInput) (entities.Invitation, error) { project, err := service.GetProjectByProjectID(member.ProjectID) diff --git a/chaoscenter/authentication/api/routes/project_router.go b/chaoscenter/authentication/api/routes/project_router.go index f1c82e0077a..4c794b0342e 100644 --- a/chaoscenter/authentication/api/routes/project_router.go +++ b/chaoscenter/authentication/api/routes/project_router.go @@ -13,6 +13,7 @@ func ProjectRouter(router *gin.Engine, service services.ApplicationService) { router.Use(middleware.JwtMiddleware(service)) router.GET("/get_project/:project_id", rest.GetProject(service)) router.GET("/get_project_members/:project_id/:state", rest.GetActiveProjectMembers(service)) + router.GET("/get_project_owners/:project_id", rest.GetActiveProjectOwners(service)) router.GET("/get_user_with_project/:username", rest.GetUserWithProject(service)) router.GET("/get_owner_projects", rest.GetOwnerProjects(service)) router.GET("/get_project_role/:project_id", rest.GetProjectRole(service)) diff --git a/chaoscenter/authentication/pkg/entities/project.go b/chaoscenter/authentication/pkg/entities/project.go index b632aeb740b..6e28ea3b46a 100644 --- a/chaoscenter/authentication/pkg/entities/project.go +++ b/chaoscenter/authentication/pkg/entities/project.go @@ -10,8 +10,8 @@ type Project struct { } type Owner struct { - UserID string `bson:"user_id" json:"userID"` - Username string `bson:"username" json:"username"` + UserID string `bson:"user_id" json:"userID"` + Username string `bson:"username" json:"username"` Invitation Invitation `bson:"invitation" json:"invitation"` JoinedAt int64 `bson:"joined_at" json:"joinedAt"` DeactivatedAt *int64 `bson:"deactivated_at,omitempty" json:"deactivatedAt,omitempty"` diff --git a/chaoscenter/authentication/pkg/project/repository.go b/chaoscenter/authentication/pkg/project/repository.go index 8037eb24374..0177e33361e 100644 --- a/chaoscenter/authentication/pkg/project/repository.go +++ b/chaoscenter/authentication/pkg/project/repository.go @@ -30,6 +30,7 @@ type Repository interface { GetOwnerProjects(ctx context.Context, userID string) ([]*entities.Project, error) GetProjectRole(projectID string, userID string) (*entities.MemberRole, error) GetProjectMembers(projectID string, state string) ([]*entities.Member, error) + GetProjectOwners(projectID string) ([]*entities.Member, error) ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) } @@ -381,6 +382,28 @@ func (r repository) GetOwnerProjects(ctx context.Context, userID string) ([]*ent return projects, nil } +// GetProjectOwners takes projectID and returns the owners +func (r repository) GetProjectOwners(projectID string) ([]*entities.Member, error) { + filter := bson.D{{"_id", projectID}} + + var project struct { + Members []*entities.Member `bson:"members"` + } + err := r.Collection.FindOne(context.TODO(), filter).Decode(&project) + if err != nil { + return err, nil + } + + // Filter the members to include only the owners + var owners []*entities.Member + for _, member := range project.Members { + if member.Role == entities.RoleOwner { + owners = append(owners, member) + } + } + return owners, nil +} + // GetProjectRole returns the role of a user in the project func (r repository) GetProjectRole(projectID string, userID string) (*entities.MemberRole, error) { filter := bson.D{ diff --git a/chaoscenter/authentication/pkg/services/project_service.go b/chaoscenter/authentication/pkg/services/project_service.go index 664f4a20e81..41759444984 100644 --- a/chaoscenter/authentication/pkg/services/project_service.go +++ b/chaoscenter/authentication/pkg/services/project_service.go @@ -25,6 +25,7 @@ type projectService interface { GetOwnerProjectIDs(ctx context.Context, userID string) ([]*entities.Project, error) GetProjectRole(projectID string, userID string) (*entities.MemberRole, error) GetProjectMembers(projectID string, state string) ([]*entities.Member, error) + GetProjectOwners(projectID string) ([]*entities.Member, error) ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) } @@ -82,6 +83,10 @@ func (a applicationService) GetProjectMembers(projectID string, state string) ([ return a.projectRepository.GetProjectMembers(projectID, state) } +func (a applicationService) GetProjectOwners(projectID string) ([]*entities.Member, error) { + return a.projectRepository.GetProjectOwners(projectID) +} + func (a applicationService) ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) { return a.projectRepository.ListInvitations(userID, invitationState) } From 0c8528e249ad05b70a568283d5f86088faf5d9e4 Mon Sep 17 00:00:00 2001 From: aryan Date: Sun, 17 Mar 2024 12:47:57 +0530 Subject: [PATCH 03/19] fix: return type error. Signed-off-by: aryan --- chaoscenter/authentication/pkg/project/repository.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaoscenter/authentication/pkg/project/repository.go b/chaoscenter/authentication/pkg/project/repository.go index 0177e33361e..fc4caaac1d3 100644 --- a/chaoscenter/authentication/pkg/project/repository.go +++ b/chaoscenter/authentication/pkg/project/repository.go @@ -391,7 +391,7 @@ func (r repository) GetProjectOwners(projectID string) ([]*entities.Member, erro } err := r.Collection.FindOne(context.TODO(), filter).Decode(&project) if err != nil { - return err, nil + return nil, err } // Filter the members to include only the owners From aeb1085b78fdab7f5919194142e74992033f34a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:40:00 +0530 Subject: [PATCH 04/19] chore(deps): Bump golang.org/x/crypto in /chaoscenter/authentication (#4527) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.18.0 to 0.21.0. - [Commits](https://github.com/golang/crypto/compare/v0.18.0...v0.21.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- chaoscenter/authentication/go.mod | 6 +++--- chaoscenter/authentication/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/chaoscenter/authentication/go.mod b/chaoscenter/authentication/go.mod index cf42ba44788..101c2227e59 100644 --- a/chaoscenter/authentication/go.mod +++ b/chaoscenter/authentication/go.mod @@ -14,7 +14,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 go.mongodb.org/mongo-driver v1.13.1 - golang.org/x/crypto v0.18.0 + golang.org/x/crypto v0.21.0 golang.org/x/oauth2 v0.16.0 google.golang.org/grpc v1.61.0 google.golang.org/protobuf v1.33.0 @@ -57,9 +57,9 @@ require ( github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/chaoscenter/authentication/go.sum b/chaoscenter/authentication/go.sum index 1468747991f..408dde8ff56 100644 --- a/chaoscenter/authentication/go.sum +++ b/chaoscenter/authentication/go.sum @@ -153,8 +153,8 @@ golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -164,8 +164,8 @@ golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= @@ -185,8 +185,8 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 64867b83facadf9eec2211ae898c2eb591255980 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:43:34 +0530 Subject: [PATCH 05/19] chore(deps): Bump follow-redirects in /chaoscenter/web (#4529) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- chaoscenter/web/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chaoscenter/web/yarn.lock b/chaoscenter/web/yarn.lock index 7efd4cd6ad4..b26456edc7b 100644 --- a/chaoscenter/web/yarn.lock +++ b/chaoscenter/web/yarn.lock @@ -4325,9 +4325,9 @@ flatted@^3.2.9: integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== follow-redirects@^1.0.0, follow-redirects@^1.15.0: - version "1.15.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" - integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== fork-ts-checker-webpack-plugin@^6.3.4: version "6.5.0" From eacb8806f74c0f4d357b6528c11236355ad3b4b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:39:07 +0530 Subject: [PATCH 06/19] chore(deps): Bump github.com/golang/protobuf (#4493) Bumps [github.com/golang/protobuf](https://github.com/golang/protobuf) from 1.5.3 to 1.5.4. - [Release notes](https://github.com/golang/protobuf/releases) - [Commits](https://github.com/golang/protobuf/compare/v1.5.3...v1.5.4) --- updated-dependencies: - dependency-name: github.com/golang/protobuf dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Raj Das --- chaoscenter/authentication/go.mod | 2 +- chaoscenter/authentication/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chaoscenter/authentication/go.mod b/chaoscenter/authentication/go.mod index 101c2227e59..2e1db325401 100644 --- a/chaoscenter/authentication/go.mod +++ b/chaoscenter/authentication/go.mod @@ -7,7 +7,7 @@ require ( github.com/gin-contrib/cors v1.3.1 github.com/gin-gonic/gin v1.9.1 github.com/golang-jwt/jwt v3.2.1+incompatible - github.com/golang/protobuf v1.5.3 + github.com/golang/protobuf v1.5.4 github.com/google/uuid v1.6.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/sirupsen/logrus v1.9.3 diff --git a/chaoscenter/authentication/go.sum b/chaoscenter/authentication/go.sum index 408dde8ff56..71bc5fd805a 100644 --- a/chaoscenter/authentication/go.sum +++ b/chaoscenter/authentication/go.sum @@ -54,8 +54,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= From 1de73daa4bc1c2143fd66005a955a7dd0bf9dfdb Mon Sep 17 00:00:00 2001 From: aryan Date: Sat, 23 Mar 2024 11:34:09 +0530 Subject: [PATCH 07/19] Modified SendInvitation API. This modification unables to send invite with the role as owner. Signed-off-by: aryan --- chaoscenter/authentication/api/handlers/rest/project_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index 2754bd3307e..ce15cb39f04 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -404,7 +404,7 @@ func SendInvitation(service services.ApplicationService) gin.HandlerFunc { return } // Validating member role - if member.Role == nil || (*member.Role != entities.RoleEditor && *member.Role != entities.RoleViewer) { + if member.Role == nil || (*member.Role != entities.RoleEditor && *member.Role != entities.RoleViewer && *member.Role != entities.RoleOwner) { c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRole], presenter.CreateErrorResponse(utils.ErrInvalidRole)) return } From 7c7981351f86a7881cf4e16e8823a581879d91e5 Mon Sep 17 00:00:00 2001 From: aryan Date: Sat, 23 Mar 2024 11:35:46 +0530 Subject: [PATCH 08/19] Modified LeaveProject API. This modification checks if the User is the last owner of the project and if not User can leave the project. Signed-off-by: aryan --- .../api/handlers/rest/project_handler.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index ce15cb39f04..b97d4503966 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -593,6 +593,20 @@ func LeaveProject(service services.ApplicationService) gin.HandlerFunc { return } + if member.Role == entities.RoleOwner { + owners, err := service.GetProjectsOwners(member.ProjectID) + if err != nil { + log.Error(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) + return + } + + if len(owners) == 1 { + c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRequest], gin.H{"message": "Cannot leave project. There must be at least one owner."}) + return + } + } + err = validations.RbacValidator(c.MustGet("uid").(string), member.ProjectID, validations.MutationRbacRules["leaveProject"], string(entities.AcceptedInvitation), From 44ae3b96518686a3f4f5d2a197cb62a830d92037 Mon Sep 17 00:00:00 2001 From: aryan Date: Sun, 24 Mar 2024 12:28:43 +0530 Subject: [PATCH 09/19] RBAC modification `LeaveProject`. Allows Owner to be able to leave the project. Signed-off-by: aryan --- chaoscenter/authentication/pkg/validations/roles.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaoscenter/authentication/pkg/validations/roles.go b/chaoscenter/authentication/pkg/validations/roles.go index eb5c8471586..99d648ac760 100644 --- a/chaoscenter/authentication/pkg/validations/roles.go +++ b/chaoscenter/authentication/pkg/validations/roles.go @@ -8,7 +8,7 @@ var MutationRbacRules = map[string][]string{ "declineInvitation": {string(entities.RoleViewer), string(entities.RoleEditor)}, "removeInvitation": {string(entities.RoleOwner)}, - "leaveProject": {string(entities.RoleViewer), string(entities.RoleEditor)}, + "leaveProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, "updateProjectName": {string(entities.RoleOwner)}, "getProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, } From 77bcd91020d2a4a59e07ca757f36192270d5a8ff Mon Sep 17 00:00:00 2001 From: aryan Date: Sun, 24 Mar 2024 12:35:41 +0530 Subject: [PATCH 10/19] Added `UpdateMemberRole` API. This API is used for updating role of the member in the project. Signed-off-by: aryan --- .../api/handlers/rest/project_handler.go | 49 +++++++++++++++++++ .../api/routes/project_router.go | 1 + .../authentication/pkg/project/repository.go | 19 +++++++ .../pkg/services/project_service.go | 5 ++ .../authentication/pkg/validations/roles.go | 1 + 5 files changed, 75 insertions(+) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index b97d4503966..76ea136e874 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -764,6 +764,55 @@ func UpdateProjectName(service services.ApplicationService) gin.HandlerFunc { } } +// UpdateMemberRole godoc +// +// @Summary Update member role. +// @Description Return updated member role. +// @Tags ProjectRouter +// @Accept json +// @Produce json +// @Failure 400 {object} response.ErrInvalidRequest +// @Failure 401 {object} response.ErrUnauthorized +// @Failure 500 {object} response.ErrServerError +// @Success 200 {object} response.Response{} +// @Router /update_member_role [post] +// +// UpdateMemberRole is used to update a member role in the project +func UpdateMemberRole(service services.ApplicationService) gin.HandlerFunc { + return func(c *gin.Context) { + var member entities.MemberInput + err := c.BindJSON(&member) + if err != nil { + log.Warn(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRequest], presenter.CreateErrorResponse(utils.ErrInvalidRequest)) + return + } + + err = validations.RbacValidator(c.MustGet("uid").(string), + member.ProjectID, + validations.MutationRbacRules["updateMemberRole"], + string(entities.AcceptedInvitation), + service) + if err != nil { + log.Warn(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], + presenter.CreateErrorResponse(utils.ErrUnauthorized)) + return + } + + err = service.UpdateMemberRole(member.ProjectID, member.UserID, member.Role) + if err != nil { + log.Error(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "Successfully updated Role", + }) + } +} + // GetOwnerProjects godoc // // @Summary Get projects owner. diff --git a/chaoscenter/authentication/api/routes/project_router.go b/chaoscenter/authentication/api/routes/project_router.go index 4c794b0342e..96a71042365 100644 --- a/chaoscenter/authentication/api/routes/project_router.go +++ b/chaoscenter/authentication/api/routes/project_router.go @@ -27,4 +27,5 @@ func ProjectRouter(router *gin.Engine, service services.ApplicationService) { router.POST("/remove_invitation", rest.RemoveInvitation(service)) router.POST("/leave_project", rest.LeaveProject(service)) router.POST("/update_project_name", rest.UpdateProjectName(service)) + router.POST("/update_member_role", rest.UpdateMemberRole(service)) } diff --git a/chaoscenter/authentication/pkg/project/repository.go b/chaoscenter/authentication/pkg/project/repository.go index fc4caaac1d3..04201851e05 100644 --- a/chaoscenter/authentication/pkg/project/repository.go +++ b/chaoscenter/authentication/pkg/project/repository.go @@ -25,6 +25,7 @@ type Repository interface { RemoveInvitation(projectID string, userID string, invitation entities.Invitation) error UpdateInvite(projectID string, userID string, invitation entities.Invitation, role *entities.MemberRole) error UpdateProjectName(projectID string, projectName string) error + UpdateMemberRole(projectID string, userID string, role *entities.MemberRole) error GetAggregateProjects(pipeline mongo.Pipeline, opts *options.AggregateOptions) (*mongo.Cursor, error) UpdateProjectState(ctx context.Context, userID string, deactivateTime int64, isDeactivate bool) error GetOwnerProjects(ctx context.Context, userID string) ([]*entities.Project, error) @@ -278,6 +279,24 @@ func (r repository) UpdateProjectName(projectID string, projectName string) erro return nil } +// UpdateMemberRole : Updates Role of the member in the project. +func (r repository) UpdateMemberRole(projectID string, userID string, role *entities.MemberRole) error { + opts := options.Update().SetArrayFilters(options.ArrayFilters{ + Filters: []interface{}{ + bson.D{{"elem.user_id", userID}}, + }, + }) + query := bson.D{{"_id", projectID}} + update := bson.D{{"$set", bson.M{"members.$[elem]role": role}}} + + _, err := r.Collection.UpdateOne(context.TODO(), query, update, opts) + if err != nil { + return err + } + + return nil +} + // GetAggregateProjects takes a mongo pipeline to retrieve the project details from the database func (r repository) GetAggregateProjects(pipeline mongo.Pipeline, opts *options.AggregateOptions) (*mongo.Cursor, error) { results, err := r.Collection.Aggregate(context.TODO(), pipeline, opts) diff --git a/chaoscenter/authentication/pkg/services/project_service.go b/chaoscenter/authentication/pkg/services/project_service.go index 41759444984..6f2d3213d69 100644 --- a/chaoscenter/authentication/pkg/services/project_service.go +++ b/chaoscenter/authentication/pkg/services/project_service.go @@ -20,6 +20,7 @@ type projectService interface { RemoveInvitation(projectID string, userID string, invitation entities.Invitation) error UpdateInvite(projectID string, userID string, invitation entities.Invitation, role *entities.MemberRole) error UpdateProjectName(projectID string, projectName string) error + UpdateMemberRole(projectID string, userID string, role *entities.MemberRole) error GetAggregateProjects(pipeline mongo.Pipeline, opts *options.AggregateOptions) (*mongo.Cursor, error) UpdateProjectState(ctx context.Context, userID string, deactivateTime int64, isDeactivate bool) error GetOwnerProjectIDs(ctx context.Context, userID string) ([]*entities.Project, error) @@ -65,6 +66,10 @@ func (a applicationService) UpdateProjectName(projectID string, projectName stri return a.projectRepository.UpdateProjectName(projectID, projectName) } +func (a applicationService) UpdateMemberRole(projectID string, userID string, role *entities.MemberRole) error { + return a.projectRepository.UpdateMemberRole(projectID, userID, role) +} + func (a applicationService) GetAggregateProjects(pipeline mongo.Pipeline, opts *options.AggregateOptions) (*mongo.Cursor, error) { return a.projectRepository.GetAggregateProjects(pipeline, opts) } diff --git a/chaoscenter/authentication/pkg/validations/roles.go b/chaoscenter/authentication/pkg/validations/roles.go index 99d648ac760..d0b70ffe461 100644 --- a/chaoscenter/authentication/pkg/validations/roles.go +++ b/chaoscenter/authentication/pkg/validations/roles.go @@ -10,5 +10,6 @@ var MutationRbacRules = map[string][]string{ "removeInvitation": {string(entities.RoleOwner)}, "leaveProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, "updateProjectName": {string(entities.RoleOwner)}, + "updateMemberRole": {string(entities.RoleOwner)}, "getProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, } From 43bd3b2efb0630f06e2b5585e4f1fb542b935028 Mon Sep 17 00:00:00 2001 From: aryan Date: Fri, 5 Apr 2024 12:23:41 +0530 Subject: [PATCH 11/19] Fixed some syntax errors. Signed-off-by: aryan --- .../authentication/api/handlers/rest/project_handler.go | 4 ++-- chaoscenter/authentication/pkg/project/repository.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index 76ea136e874..d65f649149e 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -593,8 +593,8 @@ func LeaveProject(service services.ApplicationService) gin.HandlerFunc { return } - if member.Role == entities.RoleOwner { - owners, err := service.GetProjectsOwners(member.ProjectID) + if member.Role == nil || *member.Role == entities.RoleOwner { + owners, err := service.GetProjectOwners(member.ProjectID) if err != nil { log.Error(err) c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) diff --git a/chaoscenter/authentication/pkg/project/repository.go b/chaoscenter/authentication/pkg/project/repository.go index 04201851e05..cd9ebf7f4ed 100644 --- a/chaoscenter/authentication/pkg/project/repository.go +++ b/chaoscenter/authentication/pkg/project/repository.go @@ -287,7 +287,7 @@ func (r repository) UpdateMemberRole(projectID string, userID string, role *enti }, }) query := bson.D{{"_id", projectID}} - update := bson.D{{"$set", bson.M{"members.$[elem]role": role}}} + update := bson.D{{"$set", bson.M{"members.$[elem].role": role}}} _, err := r.Collection.UpdateOne(context.TODO(), query, update, opts) if err != nil { From 2ac9f7d8b7a22a66a3b6ce97eff4dac941e8efc0 Mon Sep 17 00:00:00 2001 From: aryan Date: Fri, 5 Apr 2024 12:24:32 +0530 Subject: [PATCH 12/19] Updated roles for owner. Signed-off-by: aryan --- chaoscenter/authentication/pkg/validations/roles.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chaoscenter/authentication/pkg/validations/roles.go b/chaoscenter/authentication/pkg/validations/roles.go index d0b70ffe461..aece11514e9 100644 --- a/chaoscenter/authentication/pkg/validations/roles.go +++ b/chaoscenter/authentication/pkg/validations/roles.go @@ -4,8 +4,8 @@ import "github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/entities" var MutationRbacRules = map[string][]string{ "sendInvitation": {string(entities.RoleOwner)}, - "acceptInvitation": {string(entities.RoleViewer), string(entities.RoleEditor)}, - "declineInvitation": {string(entities.RoleViewer), + "acceptInvitation": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, + "declineInvitation": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, "removeInvitation": {string(entities.RoleOwner)}, "leaveProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, From 18607213a7004695d234e8015f412da5af3fb130 Mon Sep 17 00:00:00 2001 From: aryan Date: Tue, 9 Apr 2024 13:27:40 +0530 Subject: [PATCH 13/19] Added new API `DeleteProject`. Owner can delete project with help of this API. Signed-off-by: aryan --- .../api/handlers/rest/project_handler.go | 48 ++++++++++++++++++- .../api/routes/project_router.go | 1 + .../authentication/pkg/entities/project.go | 4 ++ .../authentication/pkg/project/repository.go | 17 +++++++ .../pkg/services/project_service.go | 5 ++ .../authentication/pkg/validations/roles.go | 1 + 6 files changed, 75 insertions(+), 1 deletion(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index d65f649149e..70003cd352d 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -209,7 +209,6 @@ func GetActiveProjectMembers(service services.ApplicationService) gin.HandlerFun func GetActiveProjectOwners(service services.ApplicationService) gin.HandlerFunc { return func(c *gin.Context) { projectID := c.Param("project_id") - // state := c.Param("state") owners, err := service.GetProjectOwners(projectID) if err != nil { c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) @@ -883,3 +882,50 @@ func GetProjectRole(service services.ApplicationService) gin.HandlerFunc { } } + +// DeleteProject godoc +// +// @Description Delete a project. +// @Tags ProjectRouter +// @Accept json +// @Produce json +// @Failure 400 {object} response.ErrProjectNotFound +// @Failure 500 {object} response.ErrServerError +// @Success 200 {object} response.Response{} +// @Router /delete_project [post] +// +// DeleteProject is used to delete a project. +func DeleteProject (service services.ApplicationService) gin.HandlerFunc { + return func(c *gin.Context) { + var deleteProjectRequest entities.DeleteProjectInput + err := c.BindJSON(&deleteProjectRequest) + if err != nil { + log.Warn(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRequest], presenter.CreateErrorResponse(utils.ErrInvalidRequest)) + return + } + + err = validations.RbacValidator(c.MustGet("uid").(string), + deleteProjectRequest.ProjectID, + validations.MutationRbacRules["deleteProject"], + string(entities.AcceptedInvitation), + service) + if err != nil { + log.Warn(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], + presenter.CreateErrorResponse(utils.ErrUnauthorized)) + return + } + + err = service.DeleteProject(deleteProjectRequest.ProjectID) + if err != nil { + log.Error(err) + c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "Successfully deleted project.", + }) + } +} \ No newline at end of file diff --git a/chaoscenter/authentication/api/routes/project_router.go b/chaoscenter/authentication/api/routes/project_router.go index 96a71042365..134cfc9b420 100644 --- a/chaoscenter/authentication/api/routes/project_router.go +++ b/chaoscenter/authentication/api/routes/project_router.go @@ -28,4 +28,5 @@ func ProjectRouter(router *gin.Engine, service services.ApplicationService) { router.POST("/leave_project", rest.LeaveProject(service)) router.POST("/update_project_name", rest.UpdateProjectName(service)) router.POST("/update_member_role", rest.UpdateMemberRole(service)) + router.POST("/delete_project", rest.DeleteProject(service)) } diff --git a/chaoscenter/authentication/pkg/entities/project.go b/chaoscenter/authentication/pkg/entities/project.go index 6e28ea3b46a..c9cbc65426f 100644 --- a/chaoscenter/authentication/pkg/entities/project.go +++ b/chaoscenter/authentication/pkg/entities/project.go @@ -54,6 +54,10 @@ type CreateProjectInput struct { UserID string `bson:"user_id" json:"userID"` } +type DeleteProjectInput struct { + ProjectID string `json:"projectID"` +} + type MemberInput struct { ProjectID string `json:"projectID"` UserID string `json:"userID"` diff --git a/chaoscenter/authentication/pkg/project/repository.go b/chaoscenter/authentication/pkg/project/repository.go index cd9ebf7f4ed..53331c86e24 100644 --- a/chaoscenter/authentication/pkg/project/repository.go +++ b/chaoscenter/authentication/pkg/project/repository.go @@ -32,6 +32,7 @@ type Repository interface { GetProjectRole(projectID string, userID string) (*entities.MemberRole, error) GetProjectMembers(projectID string, state string) ([]*entities.Member, error) GetProjectOwners(projectID string) ([]*entities.Member, error) + DeleteProject(projectID string) error ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) } @@ -598,3 +599,19 @@ func NewRepo(collection *mongo.Collection) Repository { Collection: collection, } } + +// DeleteProject deletes the project with given projectID +func (r repository) DeleteProject(projectID string) error { + query := bson.D{{"_id", projectID}} + + result, err := r.Collection.DeleteOne(context.TODO(), query) + if err != nil { + return err + } + + if result.DeletedCount == 0 { + return errors.New("no project found with the given projectID") + } + + return nil +} diff --git a/chaoscenter/authentication/pkg/services/project_service.go b/chaoscenter/authentication/pkg/services/project_service.go index 6f2d3213d69..3c5316b091f 100644 --- a/chaoscenter/authentication/pkg/services/project_service.go +++ b/chaoscenter/authentication/pkg/services/project_service.go @@ -27,6 +27,7 @@ type projectService interface { GetProjectRole(projectID string, userID string) (*entities.MemberRole, error) GetProjectMembers(projectID string, state string) ([]*entities.Member, error) GetProjectOwners(projectID string) ([]*entities.Member, error) + DeleteProject(projectID string) error ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) } @@ -95,3 +96,7 @@ func (a applicationService) GetProjectOwners(projectID string) ([]*entities.Memb func (a applicationService) ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) { return a.projectRepository.ListInvitations(userID, invitationState) } + +func (a applicationService) DeleteProject(projectID string) error { + return a.projectRepository.DeleteProject(projectID) +} diff --git a/chaoscenter/authentication/pkg/validations/roles.go b/chaoscenter/authentication/pkg/validations/roles.go index aece11514e9..7fbf999afec 100644 --- a/chaoscenter/authentication/pkg/validations/roles.go +++ b/chaoscenter/authentication/pkg/validations/roles.go @@ -11,5 +11,6 @@ var MutationRbacRules = map[string][]string{ "leaveProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, "updateProjectName": {string(entities.RoleOwner)}, "updateMemberRole": {string(entities.RoleOwner)}, + "deleteProject": {string(entities.RoleOwner)}, "getProject": {string(entities.RoleOwner), string(entities.RoleViewer), string(entities.RoleEditor)}, } From a2a27d4bb6e59bff4e2235cc87ccc883f483c62f Mon Sep 17 00:00:00 2001 From: aryan Date: Tue, 9 Apr 2024 13:29:24 +0530 Subject: [PATCH 14/19] Added mocks. Signed-off-by: aryan --- .../authentication/api/mocks/rest_mocks.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/chaoscenter/authentication/api/mocks/rest_mocks.go b/chaoscenter/authentication/api/mocks/rest_mocks.go index 80218864b50..83faca5af93 100644 --- a/chaoscenter/authentication/api/mocks/rest_mocks.go +++ b/chaoscenter/authentication/api/mocks/rest_mocks.go @@ -120,6 +120,11 @@ func (m *MockedApplicationService) UpdateProjectName(projectID, projectName stri return args.Error(0) } +func (m *MockedApplicationService) UpdateMemberRole(projectID, userID string, role *entities.MemberRole) error { + args := m.Called(projectID, userID, role) + return args.Error(0) +} + func (m *MockedApplicationService) GetAggregateProjects(pipeline mongo.Pipeline, opts *options.AggregateOptions) (*mongo.Cursor, error) { args := m.Called(pipeline, opts) return args.Get(0).(*mongo.Cursor), args.Error(1) @@ -145,6 +150,11 @@ func (m *MockedApplicationService) GetProjectMembers(projectID, state string) ([ return args.Get(0).([]*entities.Member), args.Error(1) } +func (m *MockedApplicationService) GetProjectOwners(projectID string) ([]*entities.Member, error) { + args := m.Called(projectID) + return args.Get(0).([]*entities.Member), args.Error(1) +} + func (m *MockedApplicationService) ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) { args := m.Called(userID, invitationState) return args.Get(0).([]*entities.Project), args.Error(1) @@ -199,3 +209,8 @@ func (m *MockedApplicationService) RbacValidator(userID, resourceID string, rule args := m.Called(userID, resourceID, rules, invitationStatus) return args.Error(0) } + +func (m *MockedApplicationService) DeleteProject(projectID string) error { + args := m.Called(projectID) + return args.Error(0) +} \ No newline at end of file From 737c03f3995e0e3e4c99ccf43eeca96f14e2339f Mon Sep 17 00:00:00 2001 From: aryan Date: Tue, 9 Apr 2024 14:14:05 +0530 Subject: [PATCH 15/19] modified go.sum Signed-off-by: aryan --- chaoscenter/authentication/go.sum | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chaoscenter/authentication/go.sum b/chaoscenter/authentication/go.sum index 6c8ac688ffb..7ccd088bf24 100644 --- a/chaoscenter/authentication/go.sum +++ b/chaoscenter/authentication/go.sum @@ -47,8 +47,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -139,7 +139,6 @@ golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= From c1b2ed3542e45df138a8bc93629810c05fc00327 Mon Sep 17 00:00:00 2001 From: aryan Date: Wed, 10 Apr 2024 19:09:23 +0530 Subject: [PATCH 16/19] Added condition `UpdateMemberRole`. User cannot change role of their own, so that it will avoid edge cases like 1. User is the last owner of the project. 2. User accidentally losing owner access to the projects. Signed-off-by: aryan --- .../authentication/api/handlers/rest/project_handler.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index 70003cd352d..00fc7a7bd92 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -798,7 +798,13 @@ func UpdateMemberRole(service services.ApplicationService) gin.HandlerFunc { presenter.CreateErrorResponse(utils.ErrUnauthorized)) return } - + + uid := c.MustGet("uid").(string) + if uid == member.UserID { + c.JSON(http.StatusBadRequest, gin.H{"message": "User cannot change his own role."}) + return + } + err = service.UpdateMemberRole(member.ProjectID, member.UserID, member.Role) if err != nil { log.Error(err) From 197aabd99f33c93c1a43b1afd57071bfd03a02bd Mon Sep 17 00:00:00 2001 From: aryan Date: Wed, 10 Apr 2024 19:13:43 +0530 Subject: [PATCH 17/19] made suggested changes. Signed-off-by: aryan --- chaoscenter/authentication/api/handlers/rest/project_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index 00fc7a7bd92..8291ffabb62 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -592,7 +592,7 @@ func LeaveProject(service services.ApplicationService) gin.HandlerFunc { return } - if member.Role == nil || *member.Role == entities.RoleOwner { + if member.Role != nil && *member.Role == entities.RoleOwner { owners, err := service.GetProjectOwners(member.ProjectID) if err != nil { log.Error(err) From 4a10fe3cf1da181881e27b41c0dd7d16abaee4a7 Mon Sep 17 00:00:00 2001 From: aryan Date: Thu, 11 Apr 2024 11:53:59 +0530 Subject: [PATCH 18/19] Changed DeleteProject endpoint to have url parameter. Signed-off-by: aryan --- .../api/handlers/rest/project_handler.go | 16 +++++----------- .../authentication/api/routes/project_router.go | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index 8291ffabb62..cced855b804 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -898,21 +898,15 @@ func GetProjectRole(service services.ApplicationService) gin.HandlerFunc { // @Failure 400 {object} response.ErrProjectNotFound // @Failure 500 {object} response.ErrServerError // @Success 200 {object} response.Response{} -// @Router /delete_project [post] +// @Router /delete_project/{project_id} [post] // // DeleteProject is used to delete a project. func DeleteProject (service services.ApplicationService) gin.HandlerFunc { return func(c *gin.Context) { - var deleteProjectRequest entities.DeleteProjectInput - err := c.BindJSON(&deleteProjectRequest) - if err != nil { - log.Warn(err) - c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRequest], presenter.CreateErrorResponse(utils.ErrInvalidRequest)) - return - } + projectID := c.Param("project_id") - err = validations.RbacValidator(c.MustGet("uid").(string), - deleteProjectRequest.ProjectID, + err := validations.RbacValidator(c.MustGet("uid").(string), + projectID, validations.MutationRbacRules["deleteProject"], string(entities.AcceptedInvitation), service) @@ -923,7 +917,7 @@ func DeleteProject (service services.ApplicationService) gin.HandlerFunc { return } - err = service.DeleteProject(deleteProjectRequest.ProjectID) + err = service.DeleteProject(projectID) if err != nil { log.Error(err) c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError)) diff --git a/chaoscenter/authentication/api/routes/project_router.go b/chaoscenter/authentication/api/routes/project_router.go index 134cfc9b420..1f28d5e27c0 100644 --- a/chaoscenter/authentication/api/routes/project_router.go +++ b/chaoscenter/authentication/api/routes/project_router.go @@ -28,5 +28,5 @@ func ProjectRouter(router *gin.Engine, service services.ApplicationService) { router.POST("/leave_project", rest.LeaveProject(service)) router.POST("/update_project_name", rest.UpdateProjectName(service)) router.POST("/update_member_role", rest.UpdateMemberRole(service)) - router.POST("/delete_project", rest.DeleteProject(service)) + router.POST("/delete_project/:project_id", rest.DeleteProject(service)) } From 33dec5198f192862a905107f685263f14ec3987c Mon Sep 17 00:00:00 2001 From: aryan Date: Thu, 11 Apr 2024 14:58:27 +0530 Subject: [PATCH 19/19] Minor fixes. Signed-off-by: aryan --- .../api/handlers/rest/project_handler.go | 13 ++++++++++--- .../authentication/pkg/project/repository.go | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/chaoscenter/authentication/api/handlers/rest/project_handler.go b/chaoscenter/authentication/api/handlers/rest/project_handler.go index cced855b804..d15c93c8270 100644 --- a/chaoscenter/authentication/api/handlers/rest/project_handler.go +++ b/chaoscenter/authentication/api/handlers/rest/project_handler.go @@ -591,7 +591,7 @@ func LeaveProject(service services.ApplicationService) gin.HandlerFunc { c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRequest], presenter.CreateErrorResponse(utils.ErrInvalidRequest)) return } - + if member.Role != nil && *member.Role == entities.RoleOwner { owners, err := service.GetProjectOwners(member.ProjectID) if err != nil { @@ -605,7 +605,7 @@ func LeaveProject(service services.ApplicationService) gin.HandlerFunc { return } } - + err = validations.RbacValidator(c.MustGet("uid").(string), member.ProjectID, validations.MutationRbacRules["leaveProject"], string(entities.AcceptedInvitation), @@ -787,6 +787,13 @@ func UpdateMemberRole(service services.ApplicationService) gin.HandlerFunc { return } + + // Validating member role + if member.Role == nil || (*member.Role != entities.RoleEditor && *member.Role != entities.RoleViewer && *member.Role != entities.RoleOwner) { + c.JSON(utils.ErrorStatusCodes[utils.ErrInvalidRole], presenter.CreateErrorResponse(utils.ErrInvalidRole)) + return + } + err = validations.RbacValidator(c.MustGet("uid").(string), member.ProjectID, validations.MutationRbacRules["updateMemberRole"], @@ -801,7 +808,7 @@ func UpdateMemberRole(service services.ApplicationService) gin.HandlerFunc { uid := c.MustGet("uid").(string) if uid == member.UserID { - c.JSON(http.StatusBadRequest, gin.H{"message": "User cannot change his own role."}) + c.JSON(http.StatusBadRequest, gin.H{"message": "User cannot change their own role."}) return } diff --git a/chaoscenter/authentication/pkg/project/repository.go b/chaoscenter/authentication/pkg/project/repository.go index 53331c86e24..82d5c61f4f6 100644 --- a/chaoscenter/authentication/pkg/project/repository.go +++ b/chaoscenter/authentication/pkg/project/repository.go @@ -417,7 +417,7 @@ func (r repository) GetProjectOwners(projectID string) ([]*entities.Member, erro // Filter the members to include only the owners var owners []*entities.Member for _, member := range project.Members { - if member.Role == entities.RoleOwner { + if member.Role == entities.RoleOwner && member.Invitation == entities.AcceptedInvitation { owners = append(owners, member) } }