From 4cf0cd233c05eb66db3111e4df7eea89dcb121dc Mon Sep 17 00:00:00 2001 From: konrad Date: Sat, 14 Jul 2018 18:29:24 +0200 Subject: [PATCH] Implemented team update method --- models/error.go | 17 ++++++++++++++++- models/team_members_create.go | 8 ++++++++ models/teams.go | 27 ++++++++++++++++++++++----- models/teams_create.go | 6 ++++-- models/teams_rights.go | 14 +++++++++++++- models/teams_update.go | 25 +++++++++++++++++++++++++ routes/crud/create.go | 4 ++++ routes/crud/update.go | 3 +++ routes/routes.go | 2 +- 9 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 models/team_members_create.go create mode 100644 models/teams_update.go diff --git a/models/error.go b/models/error.go index a8b22a14..55de12ec 100644 --- a/models/error.go +++ b/models/error.go @@ -358,7 +358,7 @@ func (err ErrNeedToBeNamespaceAdmin) Error() string { // Team errors // ============ -// ErrTeamNameCannotBeEmpty represents an error, where a namespace owner is empty. +// ErrTeamNameCannotBeEmpty represents an error where a team name is empty. type ErrTeamNameCannotBeEmpty struct { TeamID int64 } @@ -372,3 +372,18 @@ func IsErrTeamNameCannotBeEmpty(err error) bool { func (err ErrTeamNameCannotBeEmpty) Error() string { return fmt.Sprintf("Team name cannot be empty [Team ID: %d]", err.TeamID) } + +// ErrTeamDoesNotExist represents an error where a team does not exist +type ErrTeamDoesNotExist struct { + TeamID int64 +} + +// IsErrTeamDoesNotExist checks if an error is ErrTeamDoesNotExist. +func IsErrTeamDoesNotExist(err error) bool { + _, ok := err.(ErrTeamDoesNotExist) + return ok +} + +func (err ErrTeamDoesNotExist) Error() string { + return fmt.Sprintf("Team does not exist [Team ID: %d]", err.TeamID) +} diff --git a/models/team_members_create.go b/models/team_members_create.go new file mode 100644 index 00000000..3b9aaa59 --- /dev/null +++ b/models/team_members_create.go @@ -0,0 +1,8 @@ +package models + +// Create implements the create method to assign a user to a team +func (tm *TeamMember) Create(doer *User, id int64) (err error) { + tm.TeamID = id + _, err = x.Insert(tm) + return +} diff --git a/models/teams.go b/models/teams.go index 444b018d..1d768601 100644 --- a/models/teams.go +++ b/models/teams.go @@ -7,7 +7,7 @@ type Team struct { Description string `xorm:"varchar(250)" json:"description"` CreatedByID int64 `xorm:"int(11) not null" json:"-"` - CreatedBy *User `xorm:"-" json:"created_by"` + CreatedBy User `xorm:"-" json:"created_by"` Members []*User `xorm:"-" json:"members"` Created int64 `xorm:"created" json:"created"` @@ -25,17 +25,21 @@ func (Team) TableName() string { // AfterLoad gets the created by user object func (t *Team) AfterLoad() { // Get the owner - *t.CreatedBy, _, _ = GetUserByID(t.CreatedByID) + t.CreatedBy, _, _ = GetUserByID(t.CreatedByID) } // TeamMember defines the relationship between a user and a team type TeamMember struct { - ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"` - TeamID int64 `xorm:"int(11) not null" json:"team_id"` - UserID int64 `xorm:"int(11) not null" json:"user_id"` + ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"` + TeamID int64 `xorm:"int(11) not null" json:"team_id"` + UserID int64 `xorm:"int(11) not null" json:"user_id"` + IsAdmin bool `xorm:"tinyint(1)" json:"is_admin"` Created int64 `xorm:"created" json:"created"` Updated int64 `xorm:"updated" json:"updated"` + + CRUDable `xorm:"-" json:"-"` + Rights `xorm:"-" json:"-"` } // TableName makes beautiful table names @@ -84,3 +88,16 @@ func GetAllTeamsByNamespaceID(id int64) (teams []*Team, err error) { return } + +// GetTeamByID gets a team by its ID +func GetTeamByID(id int64) (team Team, err error) { + exists, err := x.Where("id = ?", id).Get(&team) + if err != nil { + return + } + if !exists { + return team, ErrTeamDoesNotExist{id} + } + + return +} diff --git a/models/teams_create.go b/models/teams_create.go index 128d6431..d8cefc59 100644 --- a/models/teams_create.go +++ b/models/teams_create.go @@ -7,14 +7,16 @@ func (t *Team) Create(doer *User, _ int64) (err error) { return ErrTeamNameCannotBeEmpty{} } - // Set the id to 0, otherwise the creation fails because of double keys t.CreatedByID = doer.ID - t.CreatedBy = doer + t.CreatedBy = *doer _, err = x.Insert(t) if err != nil { return } + // Insert the current user as member and admin + tm := TeamMember{TeamID: t.ID, UserID: doer.ID, IsAdmin: true} + err = tm.Create(doer, t.ID) return } diff --git a/models/teams_rights.go b/models/teams_rights.go index c2332c76..0cbb6210 100644 --- a/models/teams_rights.go +++ b/models/teams_rights.go @@ -1,7 +1,19 @@ package models // CanCreate checks if the user can create a new team -func (n *Team) CanCreate(user *User, id int64) bool { +func (t *Team) CanCreate(user *User, id int64) bool { // This is currently a dummy function, later on we could imagine global limits etc. return true } + +// CanUpdate checks if the user can update a team +func (t *Team) CanUpdate(user *User, id int64) bool { + + // Check if the current user is in the team and has admin rights in it + exists, _ := x.Where("team_id = ?", id). + And("user_id = ?", user.ID). + And("is_admin = ?", true). + Get(&TeamMember{}) + + return exists +} diff --git a/models/teams_update.go b/models/teams_update.go new file mode 100644 index 00000000..9c9d2946 --- /dev/null +++ b/models/teams_update.go @@ -0,0 +1,25 @@ +package models + +// Update is the handler to create a team +func (t *Team) Update(id int64) (err error) { + // Check if we have a name + if t.Name == "" { + return ErrTeamNameCannotBeEmpty{} + } + + // Check if the team exists + _, err = GetTeamByID(id) + if err != nil { + return + } + + _, err = x.ID(id).Update(t) + if err != nil { + return + } + + // Get the newly updated team + *t, err = GetTeamByID(id) + + return +} diff --git a/routes/crud/create.go b/routes/crud/create.go index d693d7d5..a75e28a3 100644 --- a/routes/crud/create.go +++ b/routes/crud/create.go @@ -58,6 +58,10 @@ func (c *WebHandler) CreateWeb(ctx echo.Context) error { return echo.NewHTTPError(http.StatusNotFound, "The namespace name cannot be empty.") } + if models.IsErrTeamNameCannotBeEmpty(err) { + return echo.NewHTTPError(http.StatusBadRequest, "The team name cannot be empty.") + } + return echo.NewHTTPError(http.StatusInternalServerError) } diff --git a/routes/crud/update.go b/routes/crud/update.go index 59124fbb..37e92bc4 100644 --- a/routes/crud/update.go +++ b/routes/crud/update.go @@ -1,6 +1,7 @@ package crud import ( + "fmt" "git.kolaente.de/konrad/list/models" "github.com/labstack/echo" "net/http" @@ -50,6 +51,8 @@ func (c *WebHandler) UpdateWeb(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, "The namespace owner cannot be empty.") } + fmt.Println(err) + return echo.NewHTTPError(http.StatusInternalServerError) } diff --git a/routes/routes.go b/routes/routes.go index b6109f6c..5804c2f1 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -120,5 +120,5 @@ func RegisterRoutes(e *echo.Echo) { a.GET("/teams/:id", teamHandler.ReadOneWeb) a.PUT("/teams", teamHandler.CreateWeb) a.POST("/teams/:id", teamHandler.UpdateWeb) - a.POST("/teams/:id", teamHandler.DeleteWeb) + a.DELETE("/teams/:id", teamHandler.DeleteWeb) }