mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-05-12 22:10:25 +00:00
fix: check owner when changing state of project
It was sufficiently checked for the repostiory case, but for user/org project it was not checked and you could change the state of any project by there mere knowledge of a ID.
This commit is contained in:
parent
9fca6dd456
commit
622267e547
4 changed files with 43 additions and 74 deletions
|
|
@ -307,6 +307,18 @@ func GetProjectForRepoByID(ctx context.Context, repoID, id int64) (*Project, err
|
|||
return p, nil
|
||||
}
|
||||
|
||||
// GetProjectForUserByID returns the project by id that belongs to the specified user.
|
||||
func GetProjectForUserByID(ctx context.Context, uid, id int64) (*Project, error) {
|
||||
p := new(Project)
|
||||
has, err := db.GetEngine(ctx).Where("id=? AND owner_id=?", id, uid).Get(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrProjectNotExist{ID: id}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// UpdateProject updates project properties
|
||||
func UpdateProject(ctx context.Context, p *Project) error {
|
||||
if !IsCardTypeValid(p.CardType) {
|
||||
|
|
@ -344,42 +356,26 @@ func updateRepositoryProjectCount(ctx context.Context, repoID int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ChangeProjectStatusByRepoIDAndID toggles a project between opened and closed
|
||||
func ChangeProjectStatusByRepoIDAndID(ctx context.Context, repoID, projectID int64, isClosed bool) error {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
p := new(Project)
|
||||
|
||||
has, err := db.GetEngine(ctx).ID(projectID).Where("repo_id = ?", repoID).Get(p)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrProjectNotExist{ID: projectID, RepoID: repoID}
|
||||
}
|
||||
|
||||
if err := changeProjectStatus(ctx, p, isClosed); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
func changeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
|
||||
p.IsClosed = isClosed
|
||||
p.ClosedDateUnix = timeutil.TimeStampNow()
|
||||
count, err := db.GetEngine(ctx).ID(p.ID).Where("repo_id = ? AND is_closed = ?", p.RepoID, !isClosed).Cols("is_closed", "closed_date_unix").Update(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count < 1 {
|
||||
// ChangeProjectStatus changes the status of the specified project to the state
|
||||
// specified via the `isClosed` argument.
|
||||
func ChangeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
|
||||
if p.IsClosed == isClosed {
|
||||
return nil
|
||||
}
|
||||
|
||||
return updateRepositoryProjectCount(ctx, p.RepoID)
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
p.IsClosed = isClosed
|
||||
p.ClosedDateUnix = timeutil.TimeStampNow()
|
||||
count, err := db.GetEngine(ctx).ID(p.ID).Cols("is_closed", "closed_date_unix").Update(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return updateRepositoryProjectCount(ctx, p.RepoID)
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteProjectByID deletes a project from a repository. if it's not in a database
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
"forgejo.org/models/db"
|
||||
"forgejo.org/models/unittest"
|
||||
"forgejo.org/modules/timeutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -48,42 +47,6 @@ func TestGetProjects(t *testing.T) {
|
|||
assert.Len(t, projects, 1)
|
||||
}
|
||||
|
||||
func TestProject(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
project := &Project{
|
||||
Type: TypeRepository,
|
||||
TemplateType: TemplateTypeBasicKanban,
|
||||
CardType: CardTypeTextOnly,
|
||||
Title: "New Project",
|
||||
RepoID: 1,
|
||||
CreatedUnix: timeutil.TimeStampNow(),
|
||||
CreatorID: 2,
|
||||
}
|
||||
|
||||
require.NoError(t, NewProject(db.DefaultContext, project))
|
||||
|
||||
_, err := GetProjectByID(db.DefaultContext, project.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Update project
|
||||
project.Title = "Updated title"
|
||||
require.NoError(t, UpdateProject(db.DefaultContext, project))
|
||||
|
||||
projectFromDB, err := GetProjectByID(db.DefaultContext, project.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, project.Title, projectFromDB.Title)
|
||||
|
||||
require.NoError(t, ChangeProjectStatusByRepoIDAndID(db.DefaultContext, project.RepoID, project.ID, true))
|
||||
|
||||
// Retrieve from DB afresh to check if it is truly closed
|
||||
projectFromDB, err = GetProjectByID(db.DefaultContext, project.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.True(t, projectFromDB.IsClosed)
|
||||
}
|
||||
|
||||
func TestProjectsSort(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
|
|
|
|||
|
|
@ -218,8 +218,13 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, 0, id, toClose); err != nil {
|
||||
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
|
||||
project, err := project_model.GetProjectForUserByID(ctx, ctx.ContextUser.ID, id)
|
||||
if err != nil {
|
||||
ctx.NotFoundOrServerError("GetProjectForUserByID", project_model.IsErrProjectNotExist, err)
|
||||
return
|
||||
}
|
||||
if err := project_model.ChangeProjectStatus(ctx, project, toClose); err != nil {
|
||||
ctx.ServerError("ChangeProjectStatus", err)
|
||||
return
|
||||
}
|
||||
ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.ContextUser, id))
|
||||
|
|
|
|||
|
|
@ -192,8 +192,13 @@ func ChangeProjectStatus(ctx *context.Context) {
|
|||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
|
||||
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil {
|
||||
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
|
||||
project, err := project_model.GetProjectForRepoByID(ctx, ctx.Repo.Repository.ID, id)
|
||||
if err != nil {
|
||||
ctx.NotFoundOrServerError("GetProjectForRepoByID", project_model.IsErrProjectNotExist, err)
|
||||
return
|
||||
}
|
||||
if err := project_model.ChangeProjectStatus(ctx, project, toClose); err != nil {
|
||||
ctx.ServerError("ChangeProjectStatus", err)
|
||||
return
|
||||
}
|
||||
ctx.JSONRedirect(project_model.ProjectLinkForRepo(ctx.Repo.Repository, id))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue