From ad7d485eb5ec7f7556cad7a045431d015bd83947 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 13 Sep 2023 21:24:06 +0200 Subject: [PATCH] feat(webhooks): add basic crud actions for webhooks --- pkg/migration/20230913202615.go | 50 ++++++++++++++++++ pkg/models/webhooks.go | 94 +++++++++++++++++++++++++++++++++ pkg/models/webhooks_rights.go | 42 +++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 pkg/migration/20230913202615.go create mode 100644 pkg/models/webhooks.go create mode 100644 pkg/models/webhooks_rights.go diff --git a/pkg/migration/20230913202615.go b/pkg/migration/20230913202615.go new file mode 100644 index 00000000000..1df44f1e91b --- /dev/null +++ b/pkg/migration/20230913202615.go @@ -0,0 +1,50 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package migration + +import ( + "src.techknowlogick.com/xormigrate" + "time" + "xorm.io/xorm" +) + +type webhooks20230913202615 struct { + ID int64 `xorm:"bigint autoincr not null unique pk" json:"id" param:"webhook"` + TargetURL string `xorm:"not null" valid:"minstringlength(1)" minLength:"1" json:"target_url"` + Events []string `xorm:"JSON not null" valid:"minstringlength(1)" minLength:"1" json:"event"` + ProjectID int64 `xorm:"not null" json:"project_id" param:"project"` + CreatedByID int64 `xorm:"bigint not null" json:"-"` + Created time.Time `xorm:"created not null" json:"created"` + Updated time.Time `xorm:"updated not null" json:"updated"` +} + +func (webhooks20230913202615) TableName() string { + return "webhooks" +} + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20230913202615", + Description: "", + Migrate: func(tx *xorm.Engine) error { + return tx.Sync2(webhooks20230913202615{}) + }, + Rollback: func(tx *xorm.Engine) error { + return nil + }, + }) +} diff --git a/pkg/models/webhooks.go b/pkg/models/webhooks.go new file mode 100644 index 00000000000..561b7a3611e --- /dev/null +++ b/pkg/models/webhooks.go @@ -0,0 +1,94 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package models + +import ( + "code.vikunja.io/api/pkg/user" + "code.vikunja.io/web" + "time" + "xorm.io/xorm" +) + +type Webhook struct { + ID int64 `xorm:"bigint autoincr not null unique pk" json:"id" param:"webhook"` + TargetURL string `xorm:"not null" valid:"minstringlength(1)" minLength:"1" json:"target_url"` + Events []string `xorm:"JSON not null" valid:"minstringlength(1)" minLength:"1" json:"event"` + ProjectID int64 `xorm:"not null" json:"project_id" param:"project"` + + // The user who initially created the webhook target. + CreatedBy *user.User `xorm:"-" json:"created_by" valid:"-"` + CreatedByID int64 `xorm:"bigint not null" json:"-"` + + // A timestamp when this webhook target was created. You cannot change this value. + Created time.Time `xorm:"created not null" json:"created"` + // A timestamp when this webhook target was last updated. You cannot change this value. + Updated time.Time `xorm:"updated not null" json:"updated"` + + web.CRUDable `xorm:"-" json:"-"` + web.Rights `xorm:"-" json:"-"` +} + +func (w *Webhook) TableName() string { + return "webhooks" +} + +func (w *Webhook) Create(s *xorm.Session, a web.Auth) (err error) { + // TODO: check valid webhook events + w.CreatedByID = a.GetID() + _, err = s.Insert(w) + return +} + +func (w *Webhook) ReadAll(s *xorm.Session, a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) { + p := &Project{ID: w.ProjectID} + can, _, err := p.CanRead(s, a) + if err != nil { + return nil, 0, 0, err + } + if !can { + return nil, 0, 0, ErrGenericForbidden{} + } + + ws := []*Webhook{} + err = s.Where("project_id = ?", w.ProjectID). + Limit(getLimitFromPageIndex(page, perPage)). + Find(&ws) + if err != nil { + return + } + + total, err := s.Where("project_id = ?", w.ProjectID). + Count(&Webhook{}) + if err != nil { + return + } + + return ws, len(ws), total, err +} + +func (w *Webhook) Update(s *xorm.Session, a web.Auth) (err error) { + // TODO validate webhook events + _, err = s.Where("id = ?", w.ID). + Cols("events"). + Update(w) + return +} + +func (w *Webhook) Delete(s *xorm.Session, a web.Auth) (err error) { + _, err = s.Where("id = ?", w.ID).Delete(&Webhook{}) + return +} diff --git a/pkg/models/webhooks_rights.go b/pkg/models/webhooks_rights.go new file mode 100644 index 00000000000..fed8483be20 --- /dev/null +++ b/pkg/models/webhooks_rights.go @@ -0,0 +1,42 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public Licensee as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public Licensee for more details. +// +// You should have received a copy of the GNU Affero General Public Licensee +// along with this program. If not, see . + +package models + +import ( + "code.vikunja.io/web" + "xorm.io/xorm" +) + +func (w *Webhook) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) { + p := &Project{ID: w.ProjectID} + return p.CanRead(s, a) +} + +func (w *Webhook) CanDelete(s *xorm.Session, a web.Auth) (bool, error) { + p := &Project{ID: w.ProjectID} + return p.CanUpdate(s, a) +} + +func (w *Webhook) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) { + p := &Project{ID: w.ProjectID} + return p.CanUpdate(s, a) +} + +func (w *Webhook) CanCreate(s *xorm.Session, a web.Auth) (bool, error) { + p := &Project{ID: w.ProjectID} + return p.CanUpdate(s, a) +}