Merge pull request #313 from sgotti/improve_errors_handling

*: Improve error handling
This commit is contained in:
Simone Gotti 2022-02-28 10:40:03 +01:00 committed by GitHub
commit fa7813392c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 1232 additions and 1439 deletions

View File

@ -28,7 +28,6 @@ import (
"agola.io/agola/internal/objectstorage" "agola.io/agola/internal/objectstorage"
"agola.io/agola/internal/sequence" "agola.io/agola/internal/sequence"
"agola.io/agola/internal/util"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
@ -205,7 +204,7 @@ func (d *DataManager) writeDataSnapshot(ctx context.Context, wals []*WalData) er
return err return err
} }
if err := d.ost.WriteObject(d.dataStatusPath(dataSequence), bytes.NewReader(dataStatusj), int64(len(dataStatusj)), true); err != nil { if err := d.ost.WriteObject(d.dataStatusPath(dataSequence), bytes.NewReader(dataStatusj), int64(len(dataStatusj)), true); err != nil {
return err return fromOSTError(err)
} }
return nil return nil
@ -217,7 +216,7 @@ func (d *DataManager) writeDataFile(ctx context.Context, buf *bytes.Buffer, size
} }
if err := d.ost.WriteObject(d.DataFilePath(dataType, dataFileID), buf, size, true); err != nil { if err := d.ost.WriteObject(d.DataFilePath(dataType, dataFileID), buf, size, true); err != nil {
return err return fromOSTError(err)
} }
dataFileIndexj, err := json.Marshal(dataFileIndex) dataFileIndexj, err := json.Marshal(dataFileIndex)
@ -225,7 +224,7 @@ func (d *DataManager) writeDataFile(ctx context.Context, buf *bytes.Buffer, size
return err return err
} }
if err := d.ost.WriteObject(d.DataFileIndexPath(dataType, dataFileID), bytes.NewReader(dataFileIndexj), int64(len(dataFileIndexj)), true); err != nil { if err := d.ost.WriteObject(d.DataFileIndexPath(dataType, dataFileID), bytes.NewReader(dataFileIndexj), int64(len(dataFileIndexj)), true); err != nil {
return err return fromOSTError(err)
} }
return nil return nil
@ -341,7 +340,7 @@ func (d *DataManager) writeDataType(ctx context.Context, wi walIndex, dataType s
// TODO(sgotti) instead of reading all entries in memory decode it's contents one by one when needed // TODO(sgotti) instead of reading all entries in memory decode it's contents one by one when needed
oldDataf, err := d.ost.ReadObject(d.DataFilePath(dataType, actionGroup.DataStatusFile.ID)) oldDataf, err := d.ost.ReadObject(d.DataFilePath(dataType, actionGroup.DataStatusFile.ID))
if err != nil && !objectstorage.IsNotExist(err) { if err != nil && !objectstorage.IsNotExist(err) {
return nil, err return nil, fromOSTError(err)
} }
if !objectstorage.IsNotExist(err) { if !objectstorage.IsNotExist(err) {
dec := json.NewDecoder(oldDataf) dec := json.NewDecoder(oldDataf)
@ -500,7 +499,7 @@ func (d *DataManager) Read(dataType, id string) (io.Reader, error) {
var matchingDataFileID string var matchingDataFileID string
// get the matching data file for the action entry ID // get the matching data file for the action entry ID
if len(curFiles[dataType]) == 0 { if len(curFiles[dataType]) == 0 {
return nil, util.NewErrNotExist(errors.Errorf("datatype %q doesn't exists", dataType)) return nil, newErrNotExist(errors.Errorf("datatype %q doesn't exists", dataType))
} }
matchingDataFileID = curFiles[dataType][0].ID matchingDataFileID = curFiles[dataType][0].ID
@ -513,7 +512,7 @@ func (d *DataManager) Read(dataType, id string) (io.Reader, error) {
dataFileIndexf, err := d.ost.ReadObject(d.DataFileIndexPath(dataType, matchingDataFileID)) dataFileIndexf, err := d.ost.ReadObject(d.DataFileIndexPath(dataType, matchingDataFileID))
if err != nil { if err != nil {
return nil, err return nil, fromOSTError(err)
} }
var dataFileIndex *DataFileIndex var dataFileIndex *DataFileIndex
dec := json.NewDecoder(dataFileIndexf) dec := json.NewDecoder(dataFileIndexf)
@ -526,12 +525,12 @@ func (d *DataManager) Read(dataType, id string) (io.Reader, error) {
pos, ok := dataFileIndex.Index[id] pos, ok := dataFileIndex.Index[id]
if !ok { if !ok {
return nil, util.NewErrNotExist(errors.Errorf("datatype %q, id %q doesn't exists", dataType, id)) return nil, newErrNotExist(errors.Errorf("datatype %q, id %q doesn't exists", dataType, id))
} }
dataf, err := d.ost.ReadObject(d.DataFilePath(dataType, matchingDataFileID)) dataf, err := d.ost.ReadObject(d.DataFilePath(dataType, matchingDataFileID))
if err != nil { if err != nil {
return nil, err return nil, fromOSTError(err)
} }
if _, err := dataf.Seek(int64(pos), io.SeekStart); err != nil { if _, err := dataf.Seek(int64(pos), io.SeekStart); err != nil {
dataf.Close() dataf.Close()
@ -560,7 +559,7 @@ func (d *DataManager) GetFirstDataStatusSequences(n int) ([]*sequence.Sequence,
defer close(doneCh) defer close(doneCh)
for object := range d.ost.List(d.storageDataDir()+"/", "", false, doneCh) { for object := range d.ost.List(d.storageDataDir()+"/", "", false, doneCh) {
if object.Err != nil { if object.Err != nil {
return nil, object.Err return nil, fromOSTError(object.Err)
} }
if m := DataStatusFileRegexp.FindStringSubmatch(path.Base(object.Path)); m != nil { if m := DataStatusFileRegexp.FindStringSubmatch(path.Base(object.Path)); m != nil {
seq, err := sequence.Parse(m[1]) seq, err := sequence.Parse(m[1])
@ -597,7 +596,7 @@ func (d *DataManager) GetLastDataStatusSequences(n int) ([]*sequence.Sequence, e
for object := range d.ost.List(d.storageDataDir()+"/", "", false, doneCh) { for object := range d.ost.List(d.storageDataDir()+"/", "", false, doneCh) {
if object.Err != nil { if object.Err != nil {
return nil, object.Err return nil, fromOSTError(object.Err)
} }
if m := DataStatusFileRegexp.FindStringSubmatch(path.Base(object.Path)); m != nil { if m := DataStatusFileRegexp.FindStringSubmatch(path.Base(object.Path)); m != nil {
seq, err := sequence.Parse(m[1]) seq, err := sequence.Parse(m[1])
@ -629,7 +628,7 @@ func (d *DataManager) GetLastDataStatusSequences(n int) ([]*sequence.Sequence, e
func (d *DataManager) GetDataStatus(dataSequence *sequence.Sequence) (*DataStatus, error) { func (d *DataManager) GetDataStatus(dataSequence *sequence.Sequence) (*DataStatus, error) {
dataStatusf, err := d.ost.ReadObject(d.dataStatusPath(dataSequence)) dataStatusf, err := d.ost.ReadObject(d.dataStatusPath(dataSequence))
if err != nil { if err != nil {
return nil, err return nil, fromOSTError(err)
} }
defer dataStatusf.Close() defer dataStatusf.Close()
var dataStatus *DataStatus var dataStatus *DataStatus
@ -692,7 +691,7 @@ func (d *DataManager) Export(ctx context.Context, w io.Writer) error {
for _, dsf := range curDataStatusFiles { for _, dsf := range curDataStatusFiles {
dataf, err := d.ost.ReadObject(d.DataFilePath(dataType, dsf.ID)) dataf, err := d.ost.ReadObject(d.DataFilePath(dataType, dsf.ID))
if err != nil { if err != nil {
return err return fromOSTError(err)
} }
if _, err := io.Copy(w, dataf); err != nil { if _, err := io.Copy(w, dataf); err != nil {
dataf.Close() dataf.Close()
@ -825,7 +824,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
return err return err
} }
if err := d.ost.WriteObject(d.dataStatusPath(dataSequence), bytes.NewReader(dataStatusj), int64(len(dataStatusj)), true); err != nil { if err := d.ost.WriteObject(d.dataStatusPath(dataSequence), bytes.NewReader(dataStatusj), int64(len(dataStatusj)), true); err != nil {
return err return fromOSTError(err)
} }
// initialize etcd providing the specific datastatus // initialize etcd providing the specific datastatus
@ -863,7 +862,7 @@ func (d *DataManager) cleanOldCheckpoints(ctx context.Context, dataStatusSequenc
defer close(doneCh) defer close(doneCh)
for object := range d.ost.List(d.storageDataDir()+"/", "", false, doneCh) { for object := range d.ost.List(d.storageDataDir()+"/", "", false, doneCh) {
if object.Err != nil { if object.Err != nil {
return object.Err return fromOSTError(object.Err)
} }
skip := false skip := false
@ -882,7 +881,7 @@ func (d *DataManager) cleanOldCheckpoints(ctx context.Context, dataStatusSequenc
d.log.Infof("removing %q", object.Path) d.log.Infof("removing %q", object.Path)
if err := d.ost.DeleteObject(object.Path); err != nil { if err := d.ost.DeleteObject(object.Path); err != nil {
if !objectstorage.IsNotExist(err) { if !objectstorage.IsNotExist(err) {
return err return fromOSTError(err)
} }
} }
} }
@ -910,7 +909,7 @@ func (d *DataManager) cleanOldCheckpoints(ctx context.Context, dataStatusSequenc
for object := range d.ost.List(d.storageDataDir()+"/", "", true, doneCh) { for object := range d.ost.List(d.storageDataDir()+"/", "", true, doneCh) {
if object.Err != nil { if object.Err != nil {
return object.Err return fromOSTError(object.Err)
} }
p := object.Path p := object.Path
@ -950,7 +949,7 @@ func (d *DataManager) cleanOldCheckpoints(ctx context.Context, dataStatusSequenc
d.log.Infof("removing %q", object.Path) d.log.Infof("removing %q", object.Path)
if err := d.ost.DeleteObject(object.Path); err != nil { if err := d.ost.DeleteObject(object.Path); err != nil {
if !objectstorage.IsNotExist(err) { if !objectstorage.IsNotExist(err) {
return err return fromOSTError(err)
} }
} }
} }

View File

@ -50,6 +50,35 @@ var (
ErrConcurrency = errors.New("wal concurrency error: change groups already updated") ErrConcurrency = errors.New("wal concurrency error: change groups already updated")
) )
type ErrNotExist struct {
err error
}
func newErrNotExist(err error) error {
return &ErrNotExist{err: err}
}
func (e *ErrNotExist) Error() string {
return e.err.Error()
}
func (e *ErrNotExist) Unwrap() error {
return e.err
}
func IsNotExist(err error) bool {
var e *ErrNotExist
return errors.As(err, &e)
}
func fromOSTError(err error) error {
if objectstorage.IsNotExist(err) {
return newErrNotExist(err)
}
return err
}
var ( var (
// Storage paths. Always use path (not filepath) to use the "/" separator // Storage paths. Always use path (not filepath) to use the "/" separator
storageDataDir = "data" storageDataDir = "data"

View File

@ -31,7 +31,6 @@ import (
"agola.io/agola/internal/objectstorage" "agola.io/agola/internal/objectstorage"
"agola.io/agola/internal/testutil" "agola.io/agola/internal/testutil"
"agola.io/agola/internal/util"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"go.uber.org/zap" "go.uber.org/zap"
@ -559,8 +558,8 @@ func TestReadObject(t *testing.T) {
// should not exists // should not exists
_, _, err = dm.ReadObject("datatype01", "object1", nil) _, _, err = dm.ReadObject("datatype01", "object1", nil)
if !util.IsNotExist(err) { if !IsNotExist(err) {
t.Fatalf("expected err %v, got: %v", &util.ErrNotExist{}, err) t.Fatalf("expected not exist error, got: %v", err)
} }
// should exist // should exist
_, _, err = dm.ReadObject("datatype01", "object19", nil) _, _, err = dm.ReadObject("datatype01", "object19", nil)
@ -583,8 +582,8 @@ func TestReadObject(t *testing.T) {
// should not exists // should not exists
_, _, err = dm.ReadObject("datatype01", "object1", nil) _, _, err = dm.ReadObject("datatype01", "object1", nil)
if !util.IsNotExist(err) { if !IsNotExist(err) {
t.Fatalf("expected err %v, got: %v", &util.ErrNotExist{}, err) t.Fatalf("expected not exist error, got: %v", err)
} }
// should exist // should exist
_, _, err = dm.ReadObject("datatype01", "object19", nil) _, _, err = dm.ReadObject("datatype01", "object19", nil)

View File

@ -28,7 +28,6 @@ import (
"agola.io/agola/internal/etcd" "agola.io/agola/internal/etcd"
"agola.io/agola/internal/objectstorage" "agola.io/agola/internal/objectstorage"
"agola.io/agola/internal/sequence" "agola.io/agola/internal/sequence"
"agola.io/agola/internal/util"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
etcdclientv3 "go.etcd.io/etcd/clientv3" etcdclientv3 "go.etcd.io/etcd/clientv3"
@ -124,7 +123,7 @@ func (d *DataManager) ReadObject(dataType, id string, cgNames []string) (io.Read
} }
} }
} }
return nil, nil, util.NewErrNotExist(errors.Errorf("no datatype %q, id %q in wal %s", dataType, id, walseq)) return nil, nil, newErrNotExist(errors.Errorf("no datatype %q, id %q in wal %s", dataType, id, walseq))
} }
f, err := d.Read(dataType, id) f, err := d.Read(dataType, id)
@ -137,7 +136,7 @@ func (d *DataManager) HasOSTWal(walseq string) (bool, error) {
return false, nil return false, nil
} }
if err != nil { if err != nil {
return false, err return false, fromOSTError(err)
} }
return true, nil return true, nil
} }
@ -145,7 +144,7 @@ func (d *DataManager) HasOSTWal(walseq string) (bool, error) {
func (d *DataManager) ReadWal(walseq string) (*WalHeader, error) { func (d *DataManager) ReadWal(walseq string) (*WalHeader, error) {
walFilef, err := d.ost.ReadObject(d.storageWalStatusFile(walseq) + ".committed") walFilef, err := d.ost.ReadObject(d.storageWalStatusFile(walseq) + ".committed")
if err != nil { if err != nil {
return nil, err return nil, fromOSTError(err)
} }
defer walFilef.Close() defer walFilef.Close()
dec := json.NewDecoder(walFilef) dec := json.NewDecoder(walFilef)
@ -158,7 +157,8 @@ func (d *DataManager) ReadWal(walseq string) (*WalHeader, error) {
} }
func (d *DataManager) ReadWalData(walFileID string) (io.ReadCloser, error) { func (d *DataManager) ReadWalData(walFileID string) (io.ReadCloser, error) {
return d.ost.ReadObject(d.storageWalDataFile(walFileID)) r, err := d.ost.ReadObject(d.storageWalDataFile(walFileID))
return r, fromOSTError(err)
} }
type WalFile struct { type WalFile struct {
@ -183,7 +183,7 @@ func (d *DataManager) ListOSTWals(start string) <-chan *WalFile {
for object := range d.ost.List(d.storageWalStatusDir()+"/", startPath, true, doneCh) { for object := range d.ost.List(d.storageWalStatusDir()+"/", startPath, true, doneCh) {
if object.Err != nil { if object.Err != nil {
walCh <- &WalFile{ walCh <- &WalFile{
Err: object.Err, Err: fromOSTError(object.Err),
} }
return return
} }
@ -453,7 +453,7 @@ func (d *DataManager) WriteWalAdditionalOps(ctx context.Context, actions []*Acti
} }
} }
if err := d.ost.WriteObject(walDataFilePath, bytes.NewReader(buf.Bytes()), int64(buf.Len()), true); err != nil { if err := d.ost.WriteObject(walDataFilePath, bytes.NewReader(buf.Bytes()), int64(buf.Len()), true); err != nil {
return nil, err return nil, fromOSTError(err)
} }
d.log.Debugf("wrote wal file: %s", walDataFilePath) d.log.Debugf("wrote wal file: %s", walDataFilePath)
@ -599,7 +599,7 @@ func (d *DataManager) sync(ctx context.Context) error {
walFileCommittedPath := walFilePath + ".committed" walFileCommittedPath := walFilePath + ".committed"
if err := d.ost.WriteObject(walFileCommittedPath, bytes.NewReader(headerj), int64(len(headerj)), true); err != nil { if err := d.ost.WriteObject(walFileCommittedPath, bytes.NewReader(headerj), int64(len(headerj)), true); err != nil {
return err return fromOSTError(err)
} }
d.log.Debugf("updating wal to state %q", WalStatusCommittedStorage) d.log.Debugf("updating wal to state %q", WalStatusCommittedStorage)
@ -888,7 +888,7 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
for object := range d.ost.List(d.storageWalStatusDir()+"/", "", true, doneCh) { for object := range d.ost.List(d.storageWalStatusDir()+"/", "", true, doneCh) {
if object.Err != nil { if object.Err != nil {
return err return fromOSTError(err)
} }
name := path.Base(object.Path) name := path.Base(object.Path)
ext := path.Ext(name) ext := path.Ext(name)
@ -910,7 +910,7 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
d.log.Infof("removing %q", walStatusFilePath) d.log.Infof("removing %q", walStatusFilePath)
if err := d.ost.DeleteObject(walStatusFilePath); err != nil { if err := d.ost.DeleteObject(walStatusFilePath); err != nil {
if !objectstorage.IsNotExist(err) { if !objectstorage.IsNotExist(err) {
return err return fromOSTError(err)
} }
} }
@ -918,7 +918,7 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
d.log.Infof("removing %q", object.Path) d.log.Infof("removing %q", object.Path)
if err := d.ost.DeleteObject(object.Path); err != nil { if err := d.ost.DeleteObject(object.Path); err != nil {
if !objectstorage.IsNotExist(err) { if !objectstorage.IsNotExist(err) {
return err return fromOSTError(err)
} }
} }
} }
@ -929,7 +929,7 @@ func (d *DataManager) storageWalCleaner(ctx context.Context) error {
d.log.Infof("removing %q", object.Path) d.log.Infof("removing %q", object.Path)
if err := d.ost.DeleteObject(object.Path); err != nil { if err := d.ost.DeleteObject(object.Path); err != nil {
if !objectstorage.IsNotExist(err) { if !objectstorage.IsNotExist(err) {
return err return fromOSTError(err)
} }
} }
} }
@ -1049,7 +1049,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
writeWal := func(wal *WalFile, prevWalSequence string) error { writeWal := func(wal *WalFile, prevWalSequence string) error {
walFile, err := d.ost.ReadObject(d.storageWalStatusFile(wal.WalSequence) + ".committed") walFile, err := d.ost.ReadObject(d.storageWalStatusFile(wal.WalSequence) + ".committed")
if err != nil { if err != nil {
return err return fromOSTError(err)
} }
dec := json.NewDecoder(walFile) dec := json.NewDecoder(walFile)
var header *WalHeader var header *WalHeader
@ -1200,7 +1200,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
walKey := etcdWalKey(walSequence.String()) walKey := etcdWalKey(walSequence.String())
if err := d.ost.WriteObject(walDataFilePath, bytes.NewReader([]byte{}), 0, true); err != nil { if err := d.ost.WriteObject(walDataFilePath, bytes.NewReader([]byte{}), 0, true); err != nil {
return err return fromOSTError(err)
} }
d.log.Debugf("wrote wal file: %s", walDataFilePath) d.log.Debugf("wrote wal file: %s", walDataFilePath)
@ -1216,7 +1216,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
} }
walFileCommittedPath := walFilePath + ".committed" walFileCommittedPath := walFilePath + ".committed"
if err := d.ost.WriteObject(walFileCommittedPath, bytes.NewReader(headerj), int64(len(headerj)), true); err != nil { if err := d.ost.WriteObject(walFileCommittedPath, bytes.NewReader(headerj), int64(len(headerj)), true); err != nil {
return err return fromOSTError(err)
} }
walData := &WalData{ walData := &WalData{

View File

@ -28,7 +28,7 @@ import (
gitsource "agola.io/agola/internal/gitsources" gitsource "agola.io/agola/internal/gitsources"
"agola.io/agola/internal/services/types" "agola.io/agola/internal/services/types"
errors "golang.org/x/xerrors" "agola.io/agola/internal/util"
) )
var ( var (
@ -96,20 +96,8 @@ func (c *Client) getResponse(method, path string, query url.Values, header http.
return nil, err return nil, err
} }
if resp.StatusCode/100 != 2 { if err := util.ErrFromRemote(resp); err != nil {
defer resp.Body.Close() return resp, err
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if len(data) <= 1 {
return resp, errors.New(resp.Status)
}
// TODO(sgotti) use a json error response
return resp, errors.New(string(data))
} }
return resp, nil return resp, nil

View File

@ -16,10 +16,14 @@ package action
import ( import (
"agola.io/agola/internal/datamanager" "agola.io/agola/internal/datamanager"
"agola.io/agola/internal/db"
"agola.io/agola/internal/etcd" "agola.io/agola/internal/etcd"
"agola.io/agola/internal/services/configstore/readdb" "agola.io/agola/internal/services/configstore/readdb"
"agola.io/agola/internal/util"
"agola.io/agola/services/configstore/types"
"go.uber.org/zap" "go.uber.org/zap"
errors "golang.org/x/xerrors"
) )
type ActionHandler struct { type ActionHandler struct {
@ -43,3 +47,30 @@ func NewActionHandler(logger *zap.Logger, readDB *readdb.ReadDB, dm *datamanager
func (h *ActionHandler) SetMaintenanceMode(maintenanceMode bool) { func (h *ActionHandler) SetMaintenanceMode(maintenanceMode bool) {
h.maintenanceMode = maintenanceMode h.maintenanceMode = maintenanceMode
} }
func (h *ActionHandler) ResolveConfigID(tx *db.Tx, configType types.ConfigType, ref string) (string, error) {
switch configType {
case types.ConfigTypeProjectGroup:
group, err := h.readDB.GetProjectGroup(tx, ref)
if err != nil {
return "", err
}
if group == nil {
return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("group with ref %q doesn't exists", ref))
}
return group.ID, nil
case types.ConfigTypeProject:
project, err := h.readDB.GetProject(tx, ref)
if err != nil {
return "", err
}
if project == nil {
return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with ref %q doesn't exists", ref))
}
return project.ID, nil
default:
return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("unknown config type %q", configType))
}
}

View File

@ -32,10 +32,10 @@ func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error
} }
if enable && len(resp.Kvs) > 0 { if enable && len(resp.Kvs) > 0 {
return util.NewErrBadRequest(errors.Errorf("maintenance mode already enabled")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("maintenance mode already enabled"))
} }
if !enable && len(resp.Kvs) == 0 { if !enable && len(resp.Kvs) == 0 {
return util.NewErrBadRequest(errors.Errorf("maintenance mode already disabled")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("maintenance mode already disabled"))
} }
if enable { if enable {
@ -67,7 +67,7 @@ func (h *ActionHandler) Export(ctx context.Context, w io.Writer) error {
func (h *ActionHandler) Import(ctx context.Context, r io.Reader) error { func (h *ActionHandler) Import(ctx context.Context, r io.Reader) error {
if !h.maintenanceMode { if !h.maintenanceMode {
return util.NewErrBadRequest(errors.Errorf("not in maintenance mode")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("not in maintenance mode"))
} }
return h.dm.Import(ctx, r) return h.dm.Import(ctx, r)
} }

View File

@ -51,7 +51,7 @@ func (h *ActionHandler) GetOrgMembers(ctx context.Context, orgRef string) ([]*Or
return err return err
} }
if org == nil { if org == nil {
return util.NewErrNotExist(errors.Errorf("org %q doesn't exist", orgRef)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("org %q doesn't exist", orgRef))
} }
orgUsers, err = h.readDB.GetOrgUsers(tx, org.ID) orgUsers, err = h.readDB.GetOrgUsers(tx, org.ID)
@ -71,13 +71,13 @@ func (h *ActionHandler) GetOrgMembers(ctx context.Context, orgRef string) ([]*Or
func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization) (*types.Organization, error) { func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization) (*types.Organization, error) {
if org.Name == "" { if org.Name == "" {
return nil, util.NewErrBadRequest(errors.Errorf("organization name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("organization name required"))
} }
if !util.ValidateName(org.Name) { if !util.ValidateName(org.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid organization name %q", org.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid organization name %q", org.Name))
} }
if !types.IsValidVisibility(org.Visibility) { if !types.IsValidVisibility(org.Visibility) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid organization visibility")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid organization visibility"))
} }
var cgt *datamanager.ChangeGroupsUpdateToken var cgt *datamanager.ChangeGroupsUpdateToken
@ -98,7 +98,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
return err return err
} }
if o != nil { if o != nil {
return util.NewErrBadRequest(errors.Errorf("org %q already exists", o.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q already exists", o.Name))
} }
if org.CreatorUserID != "" { if org.CreatorUserID != "" {
@ -107,7 +107,7 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, org *types.Organization)
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("creator user %q doesn't exist", org.CreatorUserID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("creator user %q doesn't exist", org.CreatorUserID))
} }
} }
@ -190,7 +190,7 @@ func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
return err return err
} }
if org == nil { if org == nil {
return util.NewErrBadRequest(errors.Errorf("org %q doesn't exist", orgRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q doesn't exist", orgRef))
} }
// changegroup is the org id // changegroup is the org id
@ -223,7 +223,7 @@ func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
// TODO(sgotti) handle invitation when implemented // TODO(sgotti) handle invitation when implemented
func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string, role types.MemberRole) (*types.OrganizationMember, error) { func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string, role types.MemberRole) (*types.OrganizationMember, error) {
if !types.IsValidMemberRole(role) { if !types.IsValidMemberRole(role) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid role %q", role)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid role %q", role))
} }
var org *types.Organization var org *types.Organization
@ -240,7 +240,7 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
return err return err
} }
if org == nil { if org == nil {
return util.NewErrBadRequest(errors.Errorf("org %q doesn't exists", orgRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q doesn't exists", orgRef))
} }
// check existing user // check existing user
user, err = h.readDB.GetUser(tx, userRef) user, err = h.readDB.GetUser(tx, userRef)
@ -248,7 +248,7 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exists", userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exists", userRef))
} }
// fetch org member if it already exist // fetch org member if it already exist
@ -316,7 +316,7 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
return err return err
} }
if org == nil { if org == nil {
return util.NewErrBadRequest(errors.Errorf("org %q doesn't exists", orgRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("org %q doesn't exists", orgRef))
} }
// check existing user // check existing user
user, err = h.readDB.GetUser(tx, userRef) user, err = h.readDB.GetUser(tx, userRef)
@ -324,7 +324,7 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exists", userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exists", userRef))
} }
// check that org member exists // check that org member exists
@ -333,7 +333,7 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
return err return err
} }
if orgmember == nil { if orgmember == nil {
return util.NewErrBadRequest(errors.Errorf("orgmember for org %q, user %q doesn't exists", orgRef, userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("orgmember for org %q, user %q doesn't exists", orgRef, userRef))
} }
cgNames := []string{util.EncodeSha256Hex(fmt.Sprintf("orgmember-%s-%s", org.ID, user.ID))} cgNames := []string{util.EncodeSha256Hex(fmt.Sprintf("orgmember-%s-%s", org.ID, user.ID))}

View File

@ -30,35 +30,35 @@ import (
func (h *ActionHandler) ValidateProject(ctx context.Context, project *types.Project) error { func (h *ActionHandler) ValidateProject(ctx context.Context, project *types.Project) error {
if project.Name == "" { if project.Name == "" {
return util.NewErrBadRequest(errors.Errorf("project name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project name required"))
} }
if !util.ValidateName(project.Name) { if !util.ValidateName(project.Name) {
return util.NewErrBadRequest(errors.Errorf("invalid project name %q", project.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project name %q", project.Name))
} }
if project.Parent.ID == "" { if project.Parent.ID == "" {
return util.NewErrBadRequest(errors.Errorf("project parent id required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project parent id required"))
} }
if project.Parent.Type != types.ConfigTypeProjectGroup { if project.Parent.Type != types.ConfigTypeProjectGroup {
return util.NewErrBadRequest(errors.Errorf("invalid project parent type %q", project.Parent.Type)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project parent type %q", project.Parent.Type))
} }
if !types.IsValidVisibility(project.Visibility) { if !types.IsValidVisibility(project.Visibility) {
return util.NewErrBadRequest(errors.Errorf("invalid project visibility")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project visibility"))
} }
if !types.IsValidRemoteRepositoryConfigType(project.RemoteRepositoryConfigType) { if !types.IsValidRemoteRepositoryConfigType(project.RemoteRepositoryConfigType) {
return util.NewErrBadRequest(errors.Errorf("invalid project remote repository config type %q", project.RemoteRepositoryConfigType)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project remote repository config type %q", project.RemoteRepositoryConfigType))
} }
if project.RemoteRepositoryConfigType == types.RemoteRepositoryConfigTypeRemoteSource { if project.RemoteRepositoryConfigType == types.RemoteRepositoryConfigTypeRemoteSource {
if project.RemoteSourceID == "" { if project.RemoteSourceID == "" {
return util.NewErrBadRequest(errors.Errorf("empty remote source id")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty remote source id"))
} }
if project.LinkedAccountID == "" { if project.LinkedAccountID == "" {
return util.NewErrBadRequest(errors.Errorf("empty linked account id")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty linked account id"))
} }
if project.RepositoryID == "" { if project.RepositoryID == "" {
return util.NewErrBadRequest(errors.Errorf("empty remote repository id")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty remote repository id"))
} }
if project.RepositoryPath == "" { if project.RepositoryPath == "" {
return util.NewErrBadRequest(errors.Errorf("empty remote repository path")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty remote repository path"))
} }
} }
return nil return nil
@ -76,7 +76,7 @@ func (h *ActionHandler) GetProject(ctx context.Context, projectRef string) (*typ
} }
if project == nil { if project == nil {
return nil, util.NewErrNotExist(errors.Errorf("project %q doesn't exist", projectRef)) return nil, util.NewAPIError(util.ErrNotExist, errors.Errorf("project %q doesn't exist", projectRef))
} }
return project, nil return project, nil
@ -97,7 +97,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
return err return err
} }
if group == nil { if group == nil {
return util.NewErrBadRequest(errors.Errorf("project group with id %q doesn't exist", project.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", project.Parent.ID))
} }
project.Parent.ID = group.ID project.Parent.ID = group.ID
@ -121,7 +121,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
return err return err
} }
if p != nil { if p != nil {
return util.NewErrBadRequest(errors.Errorf("project with name %q, path %q already exists", p.Name, pp)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with name %q, path %q already exists", p.Name, pp))
} }
if project.RemoteRepositoryConfigType == types.RemoteRepositoryConfigTypeRemoteSource { if project.RemoteRepositoryConfigType == types.RemoteRepositoryConfigTypeRemoteSource {
@ -131,14 +131,14 @@ func (h *ActionHandler) CreateProject(ctx context.Context, project *types.Projec
return errors.Errorf("failed to get user with linked account id %q: %w", project.LinkedAccountID, err) return errors.Errorf("failed to get user with linked account id %q: %w", project.LinkedAccountID, err)
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user for linked account %q doesn't exist", project.LinkedAccountID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for linked account %q doesn't exist", project.LinkedAccountID))
} }
la, ok := user.LinkedAccounts[project.LinkedAccountID] la, ok := user.LinkedAccounts[project.LinkedAccountID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("linked account id %q for user %q doesn't exist", project.LinkedAccountID, user.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("linked account id %q for user %q doesn't exist", project.LinkedAccountID, user.Name))
} }
if la.RemoteSourceID != project.RemoteSourceID { if la.RemoteSourceID != project.RemoteSourceID {
return util.NewErrBadRequest(errors.Errorf("linked account id %q remote source %q different than project remote source %q", project.LinkedAccountID, la.RemoteSourceID, project.RemoteSourceID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("linked account id %q remote source %q different than project remote source %q", project.LinkedAccountID, la.RemoteSourceID, project.RemoteSourceID))
} }
} }
@ -193,11 +193,11 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
return err return err
} }
if p == nil { if p == nil {
return util.NewErrBadRequest(errors.Errorf("project with ref %q doesn't exist", req.ProjectRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with ref %q doesn't exist", req.ProjectRef))
} }
// check that the project.ID matches // check that the project.ID matches
if p.ID != req.Project.ID { if p.ID != req.Project.ID {
return util.NewErrBadRequest(errors.Errorf("project with ref %q has a different id", req.ProjectRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with ref %q has a different id", req.ProjectRef))
} }
// check parent project group exists // check parent project group exists
@ -206,7 +206,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
return err return err
} }
if group == nil { if group == nil {
return util.NewErrBadRequest(errors.Errorf("project group with id %q doesn't exist", req.Project.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", req.Project.Parent.ID))
} }
req.Project.Parent.ID = group.ID req.Project.Parent.ID = group.ID
@ -223,7 +223,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
return err return err
} }
if ap != nil { if ap != nil {
return util.NewErrBadRequest(errors.Errorf("project with name %q, path %q already exists", req.Project.Name, pp)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project with name %q, path %q already exists", req.Project.Name, pp))
} }
} }
@ -239,7 +239,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
return err return err
} }
if curGroup == nil { if curGroup == nil {
return util.NewErrBadRequest(errors.Errorf("project group with id %q doesn't exist", p.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", p.Parent.ID))
} }
curGroupPath, err := h.readDB.GetProjectGroupPath(tx, curGroup) curGroupPath, err := h.readDB.GetProjectGroupPath(tx, curGroup)
if err != nil { if err != nil {
@ -262,14 +262,14 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, req *UpdateProjectReq
return errors.Errorf("failed to get user with linked account id %q: %w", req.Project.LinkedAccountID, err) return errors.Errorf("failed to get user with linked account id %q: %w", req.Project.LinkedAccountID, err)
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user for linked account %q doesn't exist", req.Project.LinkedAccountID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for linked account %q doesn't exist", req.Project.LinkedAccountID))
} }
la, ok := user.LinkedAccounts[req.Project.LinkedAccountID] la, ok := user.LinkedAccounts[req.Project.LinkedAccountID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("linked account id %q for user %q doesn't exist", req.Project.LinkedAccountID, user.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("linked account id %q for user %q doesn't exist", req.Project.LinkedAccountID, user.Name))
} }
if la.RemoteSourceID != req.Project.RemoteSourceID { if la.RemoteSourceID != req.Project.RemoteSourceID {
return util.NewErrBadRequest(errors.Errorf("linked account id %q remote source %q different than project remote source %q", req.Project.LinkedAccountID, la.RemoteSourceID, req.Project.RemoteSourceID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("linked account id %q remote source %q different than project remote source %q", req.Project.LinkedAccountID, la.RemoteSourceID, req.Project.RemoteSourceID))
} }
} }
@ -311,7 +311,7 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
return err return err
} }
if project == nil { if project == nil {
return util.NewErrBadRequest(errors.Errorf("project %q doesn't exist", projectRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project %q doesn't exist", projectRef))
} }
// changegroup is the project id. // changegroup is the project id.

View File

@ -41,7 +41,7 @@ func (h *ActionHandler) GetProjectGroup(ctx context.Context, projectGroupRef str
} }
if projectGroup == nil { if projectGroup == nil {
return nil, util.NewErrNotExist(errors.Errorf("project group %q doesn't exist", projectGroupRef)) return nil, util.NewAPIError(util.ErrNotExist, errors.Errorf("project group %q doesn't exist", projectGroupRef))
} }
return projectGroup, nil return projectGroup, nil
@ -57,7 +57,7 @@ func (h *ActionHandler) GetProjectGroupSubgroups(ctx context.Context, projectGro
} }
if projectGroup == nil { if projectGroup == nil {
return util.NewErrNotExist(errors.Errorf("project group %q doesn't exist", projectGroupRef)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("project group %q doesn't exist", projectGroupRef))
} }
projectGroups, err = h.readDB.GetProjectGroupSubgroups(tx, projectGroup.ID) projectGroups, err = h.readDB.GetProjectGroupSubgroups(tx, projectGroup.ID)
@ -80,7 +80,7 @@ func (h *ActionHandler) GetProjectGroupProjects(ctx context.Context, projectGrou
} }
if projectGroup == nil { if projectGroup == nil {
return util.NewErrNotExist(errors.Errorf("project group %q doesn't exist", projectGroupRef)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("project group %q doesn't exist", projectGroupRef))
} }
projects, err = h.readDB.GetProjectGroupProjects(tx, projectGroup.ID) projects, err = h.readDB.GetProjectGroupProjects(tx, projectGroup.ID)
@ -96,28 +96,28 @@ func (h *ActionHandler) ValidateProjectGroup(ctx context.Context, projectGroup *
if projectGroup.Parent.Type != types.ConfigTypeProjectGroup && if projectGroup.Parent.Type != types.ConfigTypeProjectGroup &&
projectGroup.Parent.Type != types.ConfigTypeOrg && projectGroup.Parent.Type != types.ConfigTypeOrg &&
projectGroup.Parent.Type != types.ConfigTypeUser { projectGroup.Parent.Type != types.ConfigTypeUser {
return util.NewErrBadRequest(errors.Errorf("invalid project group parent type %q", projectGroup.Parent.Type)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project group parent type %q", projectGroup.Parent.Type))
} }
if projectGroup.Parent.ID == "" { if projectGroup.Parent.ID == "" {
return util.NewErrBadRequest(errors.Errorf("project group parent id required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group parent id required"))
} }
// if the project group is a root project group the name must be empty // if the project group is a root project group the name must be empty
if projectGroup.Parent.Type == types.ConfigTypeOrg || if projectGroup.Parent.Type == types.ConfigTypeOrg ||
projectGroup.Parent.Type == types.ConfigTypeUser { projectGroup.Parent.Type == types.ConfigTypeUser {
if projectGroup.Name != "" { if projectGroup.Name != "" {
return util.NewErrBadRequest(errors.Errorf("project group name for root project group must be empty")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group name for root project group must be empty"))
} }
} else { } else {
if projectGroup.Name == "" { if projectGroup.Name == "" {
return util.NewErrBadRequest(errors.Errorf("project group name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group name required"))
} }
if !util.ValidateName(projectGroup.Name) { if !util.ValidateName(projectGroup.Name) {
return util.NewErrBadRequest(errors.Errorf("invalid project group name %q", projectGroup.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project group name %q", projectGroup.Name))
} }
} }
if !types.IsValidVisibility(projectGroup.Visibility) { if !types.IsValidVisibility(projectGroup.Visibility) {
return util.NewErrBadRequest(errors.Errorf("invalid project group visibility")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project group visibility"))
} }
return nil return nil
@ -129,7 +129,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
} }
if projectGroup.Parent.Type != types.ConfigTypeProjectGroup { if projectGroup.Parent.Type != types.ConfigTypeProjectGroup {
return nil, util.NewErrBadRequest(errors.Errorf("wrong project group parent type %q", projectGroup.Parent.Type)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong project group parent type %q", projectGroup.Parent.Type))
} }
var cgt *datamanager.ChangeGroupsUpdateToken var cgt *datamanager.ChangeGroupsUpdateToken
@ -141,7 +141,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
return err return err
} }
if parentProjectGroup == nil { if parentProjectGroup == nil {
return util.NewErrBadRequest(errors.Errorf("project group with id %q doesn't exist", projectGroup.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", projectGroup.Parent.ID))
} }
// TODO(sgotti) now we are doing a very ugly thing setting the request // TODO(sgotti) now we are doing a very ugly thing setting the request
// projectgroup parent ID that can be both an ID or a ref. Then we are fixing // projectgroup parent ID that can be both an ID or a ref. Then we are fixing
@ -168,7 +168,7 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, projectGroup *ty
return err return err
} }
if pg != nil { if pg != nil {
return util.NewErrBadRequest(errors.Errorf("project group with name %q, path %q already exists", pg.Name, pp)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with name %q, path %q already exists", pg.Name, pp))
} }
return nil return nil
}) })
@ -218,15 +218,15 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
return err return err
} }
if pg == nil { if pg == nil {
return util.NewErrBadRequest(errors.Errorf("project group with ref %q doesn't exist", req.ProjectGroupRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with ref %q doesn't exist", req.ProjectGroupRef))
} }
// check that the project group ID matches // check that the project group ID matches
if pg.ID != req.ProjectGroup.ID { if pg.ID != req.ProjectGroup.ID {
return util.NewErrBadRequest(errors.Errorf("project group with ref %q has a different id", req.ProjectGroupRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with ref %q has a different id", req.ProjectGroupRef))
} }
if pg.Parent.Type != req.ProjectGroup.Parent.Type { if pg.Parent.Type != req.ProjectGroup.Parent.Type {
return util.NewErrBadRequest(errors.Errorf("changing project group parent type isn't supported")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("changing project group parent type isn't supported"))
} }
switch req.ProjectGroup.Parent.Type { switch req.ProjectGroup.Parent.Type {
@ -235,7 +235,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
case types.ConfigTypeUser: case types.ConfigTypeUser:
// Cannot update root project group parent // Cannot update root project group parent
if pg.Parent.Type != req.ProjectGroup.Parent.Type || pg.Parent.ID != req.ProjectGroup.Parent.ID { if pg.Parent.Type != req.ProjectGroup.Parent.Type || pg.Parent.ID != req.ProjectGroup.Parent.ID {
return util.NewErrBadRequest(errors.Errorf("cannot change root project group parent type or id")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot change root project group parent type or id"))
} }
// if the project group is a root project group force the name to be empty // if the project group is a root project group force the name to be empty
req.ProjectGroup.Name = "" req.ProjectGroup.Name = ""
@ -247,7 +247,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
return err return err
} }
if group == nil { if group == nil {
return util.NewErrBadRequest(errors.Errorf("project group with id %q doesn't exist", req.ProjectGroup.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with id %q doesn't exist", req.ProjectGroup.Parent.ID))
} }
// TODO(sgotti) now we are doing a very ugly thing setting the request // TODO(sgotti) now we are doing a very ugly thing setting the request
// projectgroup parent ID that can be both an ID or a ref. Then we are fixing // projectgroup parent ID that can be both an ID or a ref. Then we are fixing
@ -274,11 +274,11 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, req *UpdateProje
return err return err
} }
if ap != nil { if ap != nil {
return util.NewErrBadRequest(errors.Errorf("project group with name %q, path %q already exists", req.ProjectGroup.Name, pgp)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group with name %q, path %q already exists", req.ProjectGroup.Name, pgp))
} }
// Cannot move inside itself or a child project group // Cannot move inside itself or a child project group
if strings.HasPrefix(pgp, curPGP+"/") { if strings.HasPrefix(pgp, curPGP+"/") {
return util.NewErrBadRequest(errors.Errorf("cannot move project group inside itself or child project group")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot move project group inside itself or child project group"))
} }
} }
@ -334,13 +334,13 @@ func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectGroupRef
return err return err
} }
if projectGroup == nil { if projectGroup == nil {
return util.NewErrBadRequest(errors.Errorf("project group %q doesn't exist", projectGroupRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("project group %q doesn't exist", projectGroupRef))
} }
// cannot delete root project group // cannot delete root project group
if projectGroup.Parent.Type == types.ConfigTypeOrg || if projectGroup.Parent.Type == types.ConfigTypeOrg ||
projectGroup.Parent.Type == types.ConfigTypeUser { projectGroup.Parent.Type == types.ConfigTypeUser {
return util.NewErrBadRequest(errors.Errorf("cannot delete root project group")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot delete root project group"))
} }
// changegroup is the project group id. // changegroup is the project group id.

View File

@ -29,35 +29,35 @@ import (
func (h *ActionHandler) ValidateRemoteSource(ctx context.Context, remoteSource *types.RemoteSource) error { func (h *ActionHandler) ValidateRemoteSource(ctx context.Context, remoteSource *types.RemoteSource) error {
if remoteSource.Name == "" { if remoteSource.Name == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource name required"))
} }
if !util.ValidateName(remoteSource.Name) { if !util.ValidateName(remoteSource.Name) {
return util.NewErrBadRequest(errors.Errorf("invalid remotesource name %q", remoteSource.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid remotesource name %q", remoteSource.Name))
} }
if remoteSource.Name == "" { if remoteSource.Name == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource name required"))
} }
if remoteSource.APIURL == "" { if remoteSource.APIURL == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource api url required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource api url required"))
} }
if remoteSource.Type == "" { if remoteSource.Type == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource type required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource type required"))
} }
if remoteSource.AuthType == "" { if remoteSource.AuthType == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource auth type required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource auth type required"))
} }
// validate if the remotesource type supports the required auth type // validate if the remotesource type supports the required auth type
if !types.SourceSupportsAuthType(types.RemoteSourceType(remoteSource.Type), types.RemoteSourceAuthType(remoteSource.AuthType)) { if !types.SourceSupportsAuthType(types.RemoteSourceType(remoteSource.Type), types.RemoteSourceAuthType(remoteSource.AuthType)) {
return util.NewErrBadRequest(errors.Errorf("remotesource type %q doesn't support auth type %q", remoteSource.Type, remoteSource.AuthType)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource type %q doesn't support auth type %q", remoteSource.Type, remoteSource.AuthType))
} }
if remoteSource.AuthType == types.RemoteSourceAuthTypeOauth2 { if remoteSource.AuthType == types.RemoteSourceAuthTypeOauth2 {
if remoteSource.Oauth2ClientID == "" { if remoteSource.Oauth2ClientID == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource oauth2clientid required for auth type %q", types.RemoteSourceAuthTypeOauth2)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource oauth2clientid required for auth type %q", types.RemoteSourceAuthTypeOauth2))
} }
if remoteSource.Oauth2ClientSecret == "" { if remoteSource.Oauth2ClientSecret == "" {
return util.NewErrBadRequest(errors.Errorf("remotesource oauth2clientsecret required for auth type %q", types.RemoteSourceAuthTypeOauth2)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource oauth2clientsecret required for auth type %q", types.RemoteSourceAuthTypeOauth2))
} }
} }
@ -87,7 +87,7 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, remoteSource *ty
return err return err
} }
if u != nil { if u != nil {
return util.NewErrBadRequest(errors.Errorf("remotesource %q already exists", u.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource %q already exists", u.Name))
} }
return nil return nil
}) })
@ -138,7 +138,7 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
return err return err
} }
if curRemoteSource == nil { if curRemoteSource == nil {
return util.NewErrBadRequest(errors.Errorf("remotesource with ref %q doesn't exist", req.RemoteSourceRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource with ref %q doesn't exist", req.RemoteSourceRef))
} }
if curRemoteSource.Name != req.RemoteSource.Name { if curRemoteSource.Name != req.RemoteSource.Name {
@ -148,7 +148,7 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
return err return err
} }
if u != nil { if u != nil {
return util.NewErrBadRequest(errors.Errorf("remotesource %q already exists", u.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource %q already exists", u.Name))
} }
} }
@ -199,7 +199,7 @@ func (h *ActionHandler) DeleteRemoteSource(ctx context.Context, remoteSourceName
return err return err
} }
if remoteSource == nil { if remoteSource == nil {
return util.NewErrBadRequest(errors.Errorf("remotesource %q doesn't exist", remoteSourceName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource %q doesn't exist", remoteSourceName))
} }
// changegroup is the remotesource id // changegroup is the remotesource id

View File

@ -39,7 +39,7 @@ func (h *ActionHandler) GetSecret(ctx context.Context, secretID string) (*types.
} }
if secret == nil { if secret == nil {
return nil, util.NewErrNotExist(errors.Errorf("secret %q doesn't exist", secretID)) return nil, util.NewAPIError(util.ErrNotExist, errors.Errorf("secret %q doesn't exist", secretID))
} }
return secret, nil return secret, nil
@ -48,7 +48,7 @@ func (h *ActionHandler) GetSecret(ctx context.Context, secretID string) (*types.
func (h *ActionHandler) GetSecrets(ctx context.Context, parentType types.ConfigType, parentRef string, tree bool) ([]*types.Secret, error) { func (h *ActionHandler) GetSecrets(ctx context.Context, parentType types.ConfigType, parentRef string, tree bool) ([]*types.Secret, error) {
var secrets []*types.Secret var secrets []*types.Secret
err := h.readDB.Do(ctx, func(tx *db.Tx) error { err := h.readDB.Do(ctx, func(tx *db.Tx) error {
parentID, err := h.readDB.ResolveConfigID(tx, parentType, parentRef) parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
if err != nil { if err != nil {
return err return err
} }
@ -68,28 +68,28 @@ func (h *ActionHandler) GetSecrets(ctx context.Context, parentType types.ConfigT
func (h *ActionHandler) ValidateSecret(ctx context.Context, secret *types.Secret) error { func (h *ActionHandler) ValidateSecret(ctx context.Context, secret *types.Secret) error {
if secret.Name == "" { if secret.Name == "" {
return util.NewErrBadRequest(errors.Errorf("secret name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret name required"))
} }
if !util.ValidateName(secret.Name) { if !util.ValidateName(secret.Name) {
return util.NewErrBadRequest(errors.Errorf("invalid secret name %q", secret.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid secret name %q", secret.Name))
} }
if secret.Type != types.SecretTypeInternal { if secret.Type != types.SecretTypeInternal {
return util.NewErrBadRequest(errors.Errorf("invalid secret type %q", secret.Type)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid secret type %q", secret.Type))
} }
switch secret.Type { switch secret.Type {
case types.SecretTypeInternal: case types.SecretTypeInternal:
if len(secret.Data) == 0 { if len(secret.Data) == 0 {
return util.NewErrBadRequest(errors.Errorf("empty secret data")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty secret data"))
} }
} }
if secret.Parent.Type == "" { if secret.Parent.Type == "" {
return util.NewErrBadRequest(errors.Errorf("secret parent type required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret parent type required"))
} }
if secret.Parent.ID == "" { if secret.Parent.ID == "" {
return util.NewErrBadRequest(errors.Errorf("secret parentid required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret parentid required"))
} }
if secret.Parent.Type != types.ConfigTypeProject && secret.Parent.Type != types.ConfigTypeProjectGroup { if secret.Parent.Type != types.ConfigTypeProject && secret.Parent.Type != types.ConfigTypeProjectGroup {
return util.NewErrBadRequest(errors.Errorf("invalid secret parent type %q", secret.Parent.Type)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid secret parent type %q", secret.Parent.Type))
} }
return nil return nil
@ -112,7 +112,7 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, secret *types.Secret)
return err return err
} }
parentID, err := h.readDB.ResolveConfigID(tx, secret.Parent.Type, secret.Parent.ID) parentID, err := h.ResolveConfigID(tx, secret.Parent.Type, secret.Parent.ID)
if err != nil { if err != nil {
return err return err
} }
@ -124,7 +124,7 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, secret *types.Secret)
return err return err
} }
if s != nil { if s != nil {
return util.NewErrBadRequest(errors.Errorf("secret with name %q for %s with id %q already exists", secret.Name, secret.Parent.Type, secret.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q for %s with id %q already exists", secret.Name, secret.Parent.Type, secret.Parent.ID))
} }
return nil return nil
@ -171,7 +171,7 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
err := h.readDB.Do(ctx, func(tx *db.Tx) error { err := h.readDB.Do(ctx, func(tx *db.Tx) error {
var err error var err error
parentID, err := h.readDB.ResolveConfigID(tx, req.Secret.Parent.Type, req.Secret.Parent.ID) parentID, err := h.ResolveConfigID(tx, req.Secret.Parent.Type, req.Secret.Parent.ID)
if err != nil { if err != nil {
return err return err
} }
@ -183,7 +183,7 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
return err return err
} }
if curSecret == nil { if curSecret == nil {
return util.NewErrBadRequest(errors.Errorf("secret with name %q for %s with id %q doesn't exists", req.SecretName, req.Secret.Parent.Type, req.Secret.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q for %s with id %q doesn't exists", req.SecretName, req.Secret.Parent.Type, req.Secret.Parent.ID))
} }
if curSecret.Name != req.Secret.Name { if curSecret.Name != req.Secret.Name {
@ -193,7 +193,7 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
return err return err
} }
if u != nil { if u != nil {
return util.NewErrBadRequest(errors.Errorf("secret with name %q for %s with id %q already exists", req.Secret.Name, req.Secret.Parent.Type, req.Secret.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q for %s with id %q already exists", req.Secret.Name, req.Secret.Parent.Type, req.Secret.Parent.ID))
} }
} }
@ -240,7 +240,7 @@ func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.Confi
// must do all the checks in a single transaction to avoid concurrent changes // must do all the checks in a single transaction to avoid concurrent changes
err := h.readDB.Do(ctx, func(tx *db.Tx) error { err := h.readDB.Do(ctx, func(tx *db.Tx) error {
var err error var err error
parentID, err := h.readDB.ResolveConfigID(tx, parentType, parentRef) parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
if err != nil { if err != nil {
return err return err
} }
@ -251,7 +251,7 @@ func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.Confi
return err return err
} }
if secret == nil { if secret == nil {
return util.NewErrBadRequest(errors.Errorf("secret with name %q doesn't exist", secretName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("secret with name %q doesn't exist", secretName))
} }
// changegroup is the secret id // changegroup is the secret id

View File

@ -37,10 +37,10 @@ type CreateUserRequest struct {
func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest) (*types.User, error) { func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest) (*types.User, error) {
if req.UserName == "" { if req.UserName == "" {
return nil, util.NewErrBadRequest(errors.Errorf("user name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user name required"))
} }
if !util.ValidateName(req.UserName) { if !util.ValidateName(req.UserName) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid user name %q", req.UserName)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid user name %q", req.UserName))
} }
var cgt *datamanager.ChangeGroupsUpdateToken var cgt *datamanager.ChangeGroupsUpdateToken
@ -63,7 +63,7 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
return err return err
} }
if u != nil { if u != nil {
return util.NewErrBadRequest(errors.Errorf("user with name %q already exists", u.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user with name %q already exists", u.Name))
} }
if req.CreateUserLARequest != nil { if req.CreateUserLARequest != nil {
@ -72,14 +72,14 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
return err return err
} }
if rs == nil { if rs == nil {
return util.NewErrBadRequest(errors.Errorf("remote source %q doesn't exist", req.CreateUserLARequest.RemoteSourceName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source %q doesn't exist", req.CreateUserLARequest.RemoteSourceName))
} }
user, err := h.readDB.GetUserByLinkedAccountRemoteUserIDandSource(tx, req.CreateUserLARequest.RemoteUserID, rs.ID) user, err := h.readDB.GetUserByLinkedAccountRemoteUserIDandSource(tx, req.CreateUserLARequest.RemoteUserID, rs.ID)
if err != nil { if err != nil {
return errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", req.CreateUserLARequest.RemoteUserID, rs.ID, err) return errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", req.CreateUserLARequest.RemoteUserID, rs.ID, err)
} }
if user != nil { if user != nil {
return util.NewErrBadRequest(errors.Errorf("user for remote user id %q for remote source %q already exists", req.CreateUserLARequest.RemoteUserID, req.CreateUserLARequest.RemoteSourceName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for remote user id %q for remote source %q already exists", req.CreateUserLARequest.RemoteUserID, req.CreateUserLARequest.RemoteSourceName))
} }
} }
return nil return nil
@ -165,7 +165,7 @@ func (h *ActionHandler) DeleteUser(ctx context.Context, userRef string) error {
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
} }
// changegroup is the userid // changegroup is the userid
@ -213,7 +213,7 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", req.UserRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", req.UserRef))
} }
cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames) cgt, err = h.readDB.GetChangeGroupsUpdateTokens(tx, cgNames)
@ -228,7 +228,7 @@ func (h *ActionHandler) UpdateUser(ctx context.Context, req *UpdateUserRequest)
return err return err
} }
if u != nil { if u != nil {
return util.NewErrBadRequest(errors.Errorf("user with name %q already exists", u.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user with name %q already exists", u.Name))
} }
// changegroup is the username (and in future the email) to ensure no // changegroup is the username (and in future the email) to ensure no
// concurrent user creation/modification using the same name // concurrent user creation/modification using the same name
@ -277,10 +277,10 @@ type CreateUserLARequest struct {
func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLARequest) (*types.LinkedAccount, error) { func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLARequest) (*types.LinkedAccount, error) {
if req.UserRef == "" { if req.UserRef == "" {
return nil, util.NewErrBadRequest(errors.Errorf("user ref required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user ref required"))
} }
if req.RemoteSourceName == "" { if req.RemoteSourceName == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remote source name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source name required"))
} }
var user *types.User var user *types.User
@ -296,7 +296,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", req.UserRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", req.UserRef))
} }
// changegroup is the userid // changegroup is the userid
@ -311,7 +311,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
return err return err
} }
if rs == nil { if rs == nil {
return util.NewErrBadRequest(errors.Errorf("remote source %q doesn't exist", req.RemoteSourceName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source %q doesn't exist", req.RemoteSourceName))
} }
user, err := h.readDB.GetUserByLinkedAccountRemoteUserIDandSource(tx, req.RemoteUserID, rs.ID) user, err := h.readDB.GetUserByLinkedAccountRemoteUserIDandSource(tx, req.RemoteUserID, rs.ID)
@ -319,7 +319,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
return errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", req.RemoteUserID, rs.ID, err) return errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", req.RemoteUserID, rs.ID, err)
} }
if user != nil { if user != nil {
return util.NewErrBadRequest(errors.Errorf("user for remote user id %q for remote source %q already exists", req.RemoteUserID, req.RemoteSourceName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user for remote user id %q for remote source %q already exists", req.RemoteUserID, req.RemoteSourceName))
} }
return nil return nil
}) })
@ -363,10 +363,10 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string) error { func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string) error {
if userRef == "" { if userRef == "" {
return util.NewErrBadRequest(errors.Errorf("user ref required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user ref required"))
} }
if laID == "" { if laID == "" {
return util.NewErrBadRequest(errors.Errorf("user linked account id required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user linked account id required"))
} }
var user *types.User var user *types.User
@ -381,7 +381,7 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
} }
// changegroup is the userid // changegroup is the userid
@ -399,7 +399,7 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
_, ok := user.LinkedAccounts[laID] _, ok := user.LinkedAccounts[laID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("linked account id %q for user %q doesn't exist", laID, userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("linked account id %q for user %q doesn't exist", laID, userRef))
} }
delete(user.LinkedAccounts, laID) delete(user.LinkedAccounts, laID)
@ -435,7 +435,7 @@ type UpdateUserLARequest struct {
func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLARequest) (*types.LinkedAccount, error) { func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLARequest) (*types.LinkedAccount, error) {
if req.UserRef == "" { if req.UserRef == "" {
return nil, util.NewErrBadRequest(errors.Errorf("user ref required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user ref required"))
} }
var user *types.User var user *types.User
@ -451,7 +451,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", req.UserRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", req.UserRef))
} }
// changegroup is the userid // changegroup is the userid
@ -463,7 +463,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
la, ok := user.LinkedAccounts[req.LinkedAccountID] la, ok := user.LinkedAccounts[req.LinkedAccountID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("linked account id %q for user %q doesn't exist", req.LinkedAccountID, user.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("linked account id %q for user %q doesn't exist", req.LinkedAccountID, user.Name))
} }
rs, err = h.readDB.GetRemoteSource(tx, la.RemoteSourceID) rs, err = h.readDB.GetRemoteSource(tx, la.RemoteSourceID)
@ -471,7 +471,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
return err return err
} }
if rs == nil { if rs == nil {
return util.NewErrBadRequest(errors.Errorf("remote source with id %q doesn't exist", la.RemoteSourceID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source with id %q doesn't exist", la.RemoteSourceID))
} }
return nil return nil
}) })
@ -507,10 +507,10 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, req *UpdateUserLAReque
func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName string) (string, error) { func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName string) (string, error) {
if userRef == "" { if userRef == "" {
return "", util.NewErrBadRequest(errors.Errorf("user ref required")) return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("user ref required"))
} }
if tokenName == "" { if tokenName == "" {
return "", util.NewErrBadRequest(errors.Errorf("token name required")) return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("token name required"))
} }
var user *types.User var user *types.User
@ -525,7 +525,7 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
} }
// changegroup is the userid // changegroup is the userid
@ -542,7 +542,7 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
} }
if user.Tokens != nil { if user.Tokens != nil {
if _, ok := user.Tokens[tokenName]; ok { if _, ok := user.Tokens[tokenName]; ok {
return "", util.NewErrBadRequest(errors.Errorf("token %q for user %q already exists", tokenName, userRef)) return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("token %q for user %q already exists", tokenName, userRef))
} }
} }
@ -572,10 +572,10 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, userRef, tokenName
func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName string) error { func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName string) error {
if userRef == "" { if userRef == "" {
return util.NewErrBadRequest(errors.Errorf("user ref required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user ref required"))
} }
if tokenName == "" { if tokenName == "" {
return util.NewErrBadRequest(errors.Errorf("token name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("token name required"))
} }
var user *types.User var user *types.User
@ -590,7 +590,7 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
return err return err
} }
if user == nil { if user == nil {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't exist", userRef))
} }
// changegroup is the userid // changegroup is the userid
@ -608,7 +608,7 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
_, ok := user.Tokens[tokenName] _, ok := user.Tokens[tokenName]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("token %q for user %q doesn't exist", tokenName, userRef)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("token %q for user %q doesn't exist", tokenName, userRef))
} }
delete(user.Tokens, tokenName) delete(user.Tokens, tokenName)
@ -651,7 +651,7 @@ func (h *ActionHandler) GetUserOrgs(ctx context.Context, userRef string) ([]*Use
return err return err
} }
if user == nil { if user == nil {
return util.NewErrNotExist(errors.Errorf("user %q doesn't exist", userRef)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("user %q doesn't exist", userRef))
} }
userOrgs, err = h.readDB.GetUserOrgs(tx, user.ID) userOrgs, err = h.readDB.GetUserOrgs(tx, user.ID)

View File

@ -30,7 +30,7 @@ import (
func (h *ActionHandler) GetVariables(ctx context.Context, parentType types.ConfigType, parentRef string, tree bool) ([]*types.Variable, error) { func (h *ActionHandler) GetVariables(ctx context.Context, parentType types.ConfigType, parentRef string, tree bool) ([]*types.Variable, error) {
var variables []*types.Variable var variables []*types.Variable
err := h.readDB.Do(ctx, func(tx *db.Tx) error { err := h.readDB.Do(ctx, func(tx *db.Tx) error {
parentID, err := h.readDB.ResolveConfigID(tx, parentType, parentRef) parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
if err != nil { if err != nil {
return err return err
} }
@ -50,22 +50,22 @@ func (h *ActionHandler) GetVariables(ctx context.Context, parentType types.Confi
func (h *ActionHandler) ValidateVariable(ctx context.Context, variable *types.Variable) error { func (h *ActionHandler) ValidateVariable(ctx context.Context, variable *types.Variable) error {
if variable.Name == "" { if variable.Name == "" {
return util.NewErrBadRequest(errors.Errorf("variable name required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable name required"))
} }
if !util.ValidateName(variable.Name) { if !util.ValidateName(variable.Name) {
return util.NewErrBadRequest(errors.Errorf("invalid variable name %q", variable.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid variable name %q", variable.Name))
} }
if len(variable.Values) == 0 { if len(variable.Values) == 0 {
return util.NewErrBadRequest(errors.Errorf("variable values required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable values required"))
} }
if variable.Parent.Type == "" { if variable.Parent.Type == "" {
return util.NewErrBadRequest(errors.Errorf("variable parent type required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable parent type required"))
} }
if variable.Parent.ID == "" { if variable.Parent.ID == "" {
return util.NewErrBadRequest(errors.Errorf("variable parent id required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable parent id required"))
} }
if variable.Parent.Type != types.ConfigTypeProject && variable.Parent.Type != types.ConfigTypeProjectGroup { if variable.Parent.Type != types.ConfigTypeProject && variable.Parent.Type != types.ConfigTypeProjectGroup {
return util.NewErrBadRequest(errors.Errorf("invalid variable parent type %q", variable.Parent.Type)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid variable parent type %q", variable.Parent.Type))
} }
return nil return nil
@ -88,7 +88,7 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, variable *types.Vari
return err return err
} }
parentID, err := h.readDB.ResolveConfigID(tx, variable.Parent.Type, variable.Parent.ID) parentID, err := h.ResolveConfigID(tx, variable.Parent.Type, variable.Parent.ID)
if err != nil { if err != nil {
return err return err
} }
@ -100,7 +100,7 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, variable *types.Vari
return err return err
} }
if s != nil { if s != nil {
return util.NewErrBadRequest(errors.Errorf("variable with name %q for %s with id %q already exists", variable.Name, variable.Parent.Type, variable.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q for %s with id %q already exists", variable.Name, variable.Parent.Type, variable.Parent.ID))
} }
return nil return nil
@ -147,7 +147,7 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
err := h.readDB.Do(ctx, func(tx *db.Tx) error { err := h.readDB.Do(ctx, func(tx *db.Tx) error {
var err error var err error
parentID, err := h.readDB.ResolveConfigID(tx, req.Variable.Parent.Type, req.Variable.Parent.ID) parentID, err := h.ResolveConfigID(tx, req.Variable.Parent.Type, req.Variable.Parent.ID)
if err != nil { if err != nil {
return err return err
} }
@ -159,7 +159,7 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
return err return err
} }
if curVariable == nil { if curVariable == nil {
return util.NewErrBadRequest(errors.Errorf("variable with name %q for %s with id %q doesn't exists", req.VariableName, req.Variable.Parent.Type, req.Variable.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q for %s with id %q doesn't exists", req.VariableName, req.Variable.Parent.Type, req.Variable.Parent.ID))
} }
if curVariable.Name != req.Variable.Name { if curVariable.Name != req.Variable.Name {
@ -169,7 +169,7 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
return err return err
} }
if u != nil { if u != nil {
return util.NewErrBadRequest(errors.Errorf("variable with name %q for %s with id %q already exists", req.Variable.Name, req.Variable.Parent.Type, req.Variable.Parent.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q for %s with id %q already exists", req.Variable.Name, req.Variable.Parent.Type, req.Variable.Parent.ID))
} }
} }
@ -216,7 +216,7 @@ func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType types.Con
// must do all the checks in a single transaction to avoid concurrent changes // must do all the checks in a single transaction to avoid concurrent changes
err := h.readDB.Do(ctx, func(tx *db.Tx) error { err := h.readDB.Do(ctx, func(tx *db.Tx) error {
var err error var err error
parentID, err := h.readDB.ResolveConfigID(tx, parentType, parentRef) parentID, err := h.ResolveConfigID(tx, parentType, parentRef)
if err != nil { if err != nil {
return err return err
} }
@ -227,7 +227,7 @@ func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType types.Con
return err return err
} }
if variable == nil { if variable == nil {
return util.NewErrBadRequest(errors.Errorf("variable with name %q doesn't exist", variableName)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("variable with name %q doesn't exist", variableName))
} }
// changegroup is the variable id // changegroup is the variable id

View File

@ -15,7 +15,6 @@
package api package api
import ( import (
"encoding/json"
"net/http" "net/http"
"net/url" "net/url"
@ -30,97 +29,11 @@ type ErrorResponse struct {
Message string `json:"message"` Message string `json:"message"`
} }
func ErrorResponseFromError(err error) *ErrorResponse {
var aerr error
// use inner errors if of these types
switch {
case util.IsBadRequest(err):
var cerr *util.ErrBadRequest
errors.As(err, &cerr)
aerr = cerr
case util.IsNotExist(err):
var cerr *util.ErrNotExist
errors.As(err, &cerr)
aerr = cerr
case util.IsForbidden(err):
var cerr *util.ErrForbidden
errors.As(err, &cerr)
aerr = cerr
case util.IsUnauthorized(err):
var cerr *util.ErrUnauthorized
errors.As(err, &cerr)
aerr = cerr
case util.IsInternal(err):
var cerr *util.ErrInternal
errors.As(err, &cerr)
aerr = cerr
}
if aerr != nil {
return &ErrorResponse{Message: aerr.Error()}
}
// on generic error return an generic message to not leak the real error
return &ErrorResponse{Message: "internal server error"}
}
func httpError(w http.ResponseWriter, err error) bool {
if err == nil {
return false
}
response := ErrorResponseFromError(err)
resj, merr := json.Marshal(response)
if merr != nil {
w.WriteHeader(http.StatusInternalServerError)
return true
}
switch {
case util.IsBadRequest(err):
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write(resj)
case util.IsNotExist(err):
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write(resj)
case util.IsForbidden(err):
w.WriteHeader(http.StatusForbidden)
_, _ = w.Write(resj)
case util.IsUnauthorized(err):
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write(resj)
case util.IsInternal(err):
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write(resj)
default:
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write(resj)
}
return true
}
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
w.Header().Set("Content-Type", "application/json")
if res != nil {
resj, err := json.Marshal(res)
if err != nil {
httpError(w, err)
return err
}
w.WriteHeader(code)
_, err = w.Write(resj)
return err
}
w.WriteHeader(code)
return nil
}
func GetConfigTypeRef(r *http.Request) (types.ConfigType, string, error) { func GetConfigTypeRef(r *http.Request) (types.ConfigType, string, error) {
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
return "", "", util.NewErrBadRequest(errors.Errorf("wrong projectref %q: %w", vars["projectref"], err)) return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong projectref %q: %w", vars["projectref"], err))
} }
if projectRef != "" { if projectRef != "" {
return types.ConfigTypeProject, projectRef, nil return types.ConfigTypeProject, projectRef, nil
@ -128,11 +41,11 @@ func GetConfigTypeRef(r *http.Request) (types.ConfigType, string, error) {
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
return "", "", util.NewErrBadRequest(errors.Errorf("wrong projectgroupref %q: %w", vars["projectgroupref"], err)) return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong projectgroupref %q: %w", vars["projectgroupref"], err))
} }
if projectGroupRef != "" { if projectGroupRef != "" {
return types.ConfigTypeProjectGroup, projectGroupRef, nil return types.ConfigTypeProjectGroup, projectGroupRef, nil
} }
return "", "", util.NewErrBadRequest(errors.Errorf("cannot get project or projectgroup ref")) return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot get project or projectgroup ref"))
} }

View File

@ -19,6 +19,7 @@ import (
"agola.io/agola/internal/etcd" "agola.io/agola/internal/etcd"
"agola.io/agola/internal/services/configstore/action" "agola.io/agola/internal/services/configstore/action"
"agola.io/agola/internal/util"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -47,11 +48,11 @@ func (h *MaintenanceModeHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
err := h.ah.MaintenanceMode(ctx, enable) err := h.ah.MaintenanceMode(ctx, enable)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, nil); err != nil { if err := util.HTTPResponse(w, http.StatusOK, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
@ -96,11 +97,11 @@ func (h *ImportHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := h.ah.Import(ctx, r.Body) err := h.ah.Import(ctx, r.Body)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, nil); err != nil { if err := util.HTTPResponse(w, http.StatusOK, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }

View File

@ -53,16 +53,16 @@ func (h *OrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if org == nil { if org == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("org %q doesn't exist", orgRef))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("org %q doesn't exist", orgRef)))
return return
} }
if err := httpResponse(w, http.StatusOK, org); err != nil { if err := util.HTTPResponse(w, http.StatusOK, org); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -82,17 +82,17 @@ func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req types.Organization var req types.Organization
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
org, err := h.ah.CreateOrg(ctx, &req) org, err := h.ah.CreateOrg(ctx, &req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, org); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, org); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -113,11 +113,11 @@ func (h *DeleteOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
orgRef := vars["orgref"] orgRef := vars["orgref"]
err := h.ah.DeleteOrg(ctx, orgRef) err := h.ah.DeleteOrg(ctx, orgRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -146,12 +146,12 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxOrgsLimit { if limit > MaxOrgsLimit {
@ -172,11 +172,11 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, orgs); err != nil { if err := util.HTTPResponse(w, http.StatusOK, orgs); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -200,17 +200,17 @@ func (h *AddOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req csapitypes.AddOrgMemberRequest var req csapitypes.AddOrgMemberRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
org, err := h.ah.AddOrgMember(ctx, orgRef, userRef, req.Role) org, err := h.ah.AddOrgMember(ctx, orgRef, userRef, req.Role)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, org); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, org); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -232,12 +232,12 @@ func (h *RemoveOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
userRef := vars["userref"] userRef := vars["userref"]
err := h.ah.RemoveOrgMember(ctx, orgRef, userRef) err := h.ah.RemoveOrgMember(ctx, orgRef, userRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -264,7 +264,7 @@ func (h *OrgMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
orgRef := vars["orgref"] orgRef := vars["orgref"]
orgUsers, err := h.ah.GetOrgMembers(ctx, orgRef) orgUsers, err := h.ah.GetOrgMembers(ctx, orgRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -274,7 +274,7 @@ func (h *OrgMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
res[i] = orgMemberResponse(orgUser) res[i] = orgMemberResponse(orgUser)
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -126,23 +126,23 @@ func (h *ProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
project, err := h.ah.GetProject(ctx, projectRef) project, err := h.ah.GetProject(ctx, projectRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProject, err := projectResponse(ctx, h.readDB, project) resProject, err := projectResponse(ctx, h.readDB, project)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, resProject); err != nil { if err := util.HTTPResponse(w, http.StatusOK, resProject); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -163,23 +163,23 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req types.Project var req types.Project
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
project, err := h.ah.CreateProject(ctx, &req) project, err := h.ah.CreateProject(ctx, &req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProject, err := projectResponse(ctx, h.readDB, project) resProject, err := projectResponse(ctx, h.readDB, project)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, resProject); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, resProject); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -200,14 +200,14 @@ func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
var project *types.Project var project *types.Project
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&project); err != nil { if err := d.Decode(&project); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -216,18 +216,18 @@ func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Project: project, Project: project,
} }
project, err = h.ah.UpdateProject(ctx, areq) project, err = h.ah.UpdateProject(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProject, err := projectResponse(ctx, h.readDB, project) resProject, err := projectResponse(ctx, h.readDB, project)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, resProject); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, resProject); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -247,15 +247,15 @@ func (h *DeleteProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
err = h.ah.DeleteProject(ctx, projectRef) err = h.ah.DeleteProject(ctx, projectRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -95,23 +95,23 @@ func (h *ProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
projectGroup, err := h.ah.GetProjectGroup(ctx, projectGroupRef) projectGroup, err := h.ah.GetProjectGroup(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProjectGroup, err := projectGroupResponse(ctx, h.readDB, projectGroup) resProjectGroup, err := projectGroupResponse(ctx, h.readDB, projectGroup)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, resProjectGroup); err != nil { if err := util.HTTPResponse(w, http.StatusOK, resProjectGroup); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -132,23 +132,23 @@ func (h *ProjectGroupProjectsHandler) ServeHTTP(w http.ResponseWriter, r *http.R
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
projects, err := h.ah.GetProjectGroupProjects(ctx, projectGroupRef) projects, err := h.ah.GetProjectGroupProjects(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProjects, err := projectsResponse(ctx, h.readDB, projects) resProjects, err := projectsResponse(ctx, h.readDB, projects)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, resProjects); err != nil { if err := util.HTTPResponse(w, http.StatusOK, resProjects); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -168,23 +168,23 @@ func (h *ProjectGroupSubgroupsHandler) ServeHTTP(w http.ResponseWriter, r *http.
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
projectGroups, err := h.ah.GetProjectGroupSubgroups(ctx, projectGroupRef) projectGroups, err := h.ah.GetProjectGroupSubgroups(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProjectGroups, err := projectGroupsResponse(ctx, h.readDB, projectGroups) resProjectGroups, err := projectGroupsResponse(ctx, h.readDB, projectGroups)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, resProjectGroups); err != nil { if err := util.HTTPResponse(w, http.StatusOK, resProjectGroups); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -205,23 +205,23 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
var req types.ProjectGroup var req types.ProjectGroup
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
projectGroup, err := h.ah.CreateProjectGroup(ctx, &req) projectGroup, err := h.ah.CreateProjectGroup(ctx, &req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProjectGroup, err := projectGroupResponse(ctx, h.readDB, projectGroup) resProjectGroup, err := projectGroupResponse(ctx, h.readDB, projectGroup)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, resProjectGroup); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, resProjectGroup); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -242,14 +242,14 @@ func (h *UpdateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
var projectGroup *types.ProjectGroup var projectGroup *types.ProjectGroup
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&projectGroup); err != nil { if err := d.Decode(&projectGroup); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -258,18 +258,18 @@ func (h *UpdateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
ProjectGroup: projectGroup, ProjectGroup: projectGroup,
} }
projectGroup, err = h.ah.UpdateProjectGroup(ctx, areq) projectGroup, err = h.ah.UpdateProjectGroup(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
resProjectGroup, err := projectGroupResponse(ctx, h.readDB, projectGroup) resProjectGroup, err := projectGroupResponse(ctx, h.readDB, projectGroup)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, resProjectGroup); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, resProjectGroup); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -289,15 +289,15 @@ func (h *DeleteProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
err = h.ah.DeleteProjectGroup(ctx, projectGroupRef) err = h.ah.DeleteProjectGroup(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -52,16 +52,16 @@ func (h *RemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if remoteSource == nil { if remoteSource == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("remote source %q doesn't exist", rsRef))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("remote source %q doesn't exist", rsRef)))
return return
} }
if err := httpResponse(w, http.StatusOK, remoteSource); err != nil { if err := util.HTTPResponse(w, http.StatusOK, remoteSource); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -81,17 +81,17 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
var req types.RemoteSource var req types.RemoteSource
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
remoteSource, err := h.ah.CreateRemoteSource(ctx, &req) remoteSource, err := h.ah.CreateRemoteSource(ctx, &req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, remoteSource); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, remoteSource); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -114,7 +114,7 @@ func (h *UpdateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
var remoteSource *types.RemoteSource var remoteSource *types.RemoteSource
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&remoteSource); err != nil { if err := d.Decode(&remoteSource); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -123,12 +123,12 @@ func (h *UpdateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
RemoteSource: remoteSource, RemoteSource: remoteSource,
} }
remoteSource, err := h.ah.UpdateRemoteSource(ctx, areq) remoteSource, err := h.ah.UpdateRemoteSource(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, remoteSource); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, remoteSource); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -149,10 +149,10 @@ func (h *DeleteRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
rsRef := vars["remotesourceref"] rsRef := vars["remotesourceref"]
err := h.ah.DeleteRemoteSource(ctx, rsRef) err := h.ah.DeleteRemoteSource(ctx, rsRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -181,12 +181,12 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxRemoteSourcesLimit { if limit > MaxRemoteSourcesLimit {
@ -202,11 +202,11 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
remoteSources, err := h.readDB.GetRemoteSources(ctx, start, limit, asc) remoteSources, err := h.readDB.GetRemoteSources(ctx, start, limit, asc)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, remoteSources); err != nil { if err := util.HTTPResponse(w, http.StatusOK, remoteSources); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -45,12 +45,12 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
secretID := vars["secretid"] secretID := vars["secretid"]
secret, err := h.ah.GetSecret(ctx, secretID) secret, err := h.ah.GetSecret(ctx, secretID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, secret); err != nil { if err := util.HTTPResponse(w, http.StatusOK, secret); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -71,13 +71,13 @@ func (h *SecretsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, tree := query["tree"] _, tree := query["tree"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
secrets, err := h.ah.GetSecrets(ctx, parentType, parentRef, tree) secrets, err := h.ah.GetSecrets(ctx, parentType, parentRef, tree)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -100,11 +100,11 @@ func (h *SecretsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, resSecrets); err != nil { if err := util.HTTPResponse(w, http.StatusOK, resSecrets); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -121,7 +121,7 @@ func NewCreateSecretHandler(logger *zap.Logger, ah *action.ActionHandler) *Creat
func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -129,7 +129,7 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var secret *types.Secret var secret *types.Secret
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&secret); err != nil { if err := d.Decode(&secret); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -137,12 +137,12 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
secret.Parent.ID = parentRef secret.Parent.ID = parentRef
secret, err = h.ah.CreateSecret(ctx, secret) secret, err = h.ah.CreateSecret(ctx, secret)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, secret); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, secret); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -162,7 +162,7 @@ func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
secretName := vars["secretname"] secretName := vars["secretname"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -170,7 +170,7 @@ func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var secret *types.Secret var secret *types.Secret
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&secret); err != nil { if err := d.Decode(&secret); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -182,12 +182,12 @@ func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Secret: secret, Secret: secret,
} }
secret, err = h.ah.UpdateSecret(ctx, areq) secret, err = h.ah.UpdateSecret(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, secret); err != nil { if err := util.HTTPResponse(w, http.StatusOK, secret); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -207,16 +207,16 @@ func (h *DeleteSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
secretName := vars["secretname"] secretName := vars["secretname"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
err = h.ah.DeleteSecret(ctx, parentType, parentRef, secretName) err = h.ah.DeleteSecret(ctx, parentType, parentRef, secretName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -53,16 +53,16 @@ func (h *UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if user == nil { if user == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("user %q doesn't exist", userRef))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("user %q doesn't exist", userRef)))
return return
} }
if err := httpResponse(w, http.StatusOK, user); err != nil { if err := util.HTTPResponse(w, http.StatusOK, user); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -82,7 +82,7 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req *csapitypes.CreateUserRequest var req *csapitypes.CreateUserRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -102,12 +102,12 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
user, err := h.ah.CreateUser(ctx, creq) user, err := h.ah.CreateUser(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, user); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, user); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -130,7 +130,7 @@ func (h *UpdateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req *csapitypes.UpdateUserRequest var req *csapitypes.UpdateUserRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -140,12 +140,12 @@ func (h *UpdateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
user, err := h.ah.UpdateUser(ctx, creq) user, err := h.ah.UpdateUser(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, user); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, user); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -166,10 +166,10 @@ func (h *DeleteUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
userRef := vars["userref"] userRef := vars["userref"]
err := h.ah.DeleteUser(ctx, userRef) err := h.ah.DeleteUser(ctx, userRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -198,12 +198,12 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxUsersLimit { if limit > MaxUsersLimit {
@ -231,11 +231,11 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if user == nil { if user == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("user with required token doesn't exist"))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("user with required token doesn't exist")))
return return
} }
users = []*types.User{user} users = []*types.User{user}
@ -249,11 +249,11 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if user == nil { if user == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("user with linked account %q token doesn't exist", linkedAccountID))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("user with linked account %q token doesn't exist", linkedAccountID)))
return return
} }
users = []*types.User{user} users = []*types.User{user}
@ -268,11 +268,11 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if user == nil { if user == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("user with remote user %q for remote source %q token doesn't exist", remoteUserID, remoteSourceID))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("user with remote user %q for remote source %q token doesn't exist", remoteUserID, remoteSourceID)))
return return
} }
users = []*types.User{user} users = []*types.User{user}
@ -285,12 +285,12 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
} }
if err := httpResponse(w, http.StatusOK, users); err != nil { if err := util.HTTPResponse(w, http.StatusOK, users); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -312,7 +312,7 @@ func (h *CreateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req csapitypes.CreateUserLARequest var req csapitypes.CreateUserLARequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -327,12 +327,12 @@ func (h *CreateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Oauth2AccessTokenExpiresAt: req.Oauth2AccessTokenExpiresAt, Oauth2AccessTokenExpiresAt: req.Oauth2AccessTokenExpiresAt,
} }
user, err := h.ah.CreateUserLA(ctx, creq) user, err := h.ah.CreateUserLA(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, user); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, user); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -353,10 +353,10 @@ func (h *DeleteUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
laID := vars["laid"] laID := vars["laid"]
err := h.ah.DeleteUserLA(ctx, userRef, laID) err := h.ah.DeleteUserLA(ctx, userRef, laID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -379,7 +379,7 @@ func (h *UpdateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req csapitypes.UpdateUserLARequest var req csapitypes.UpdateUserLARequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -394,12 +394,12 @@ func (h *UpdateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Oauth2AccessTokenExpiresAt: req.Oauth2AccessTokenExpiresAt, Oauth2AccessTokenExpiresAt: req.Oauth2AccessTokenExpiresAt,
} }
user, err := h.ah.UpdateUserLA(ctx, creq) user, err := h.ah.UpdateUserLA(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, user); err != nil { if err := util.HTTPResponse(w, http.StatusOK, user); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -421,12 +421,12 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
var req csapitypes.CreateUserTokenRequest var req csapitypes.CreateUserTokenRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
token, err := h.ah.CreateUserToken(ctx, userRef, req.TokenName) token, err := h.ah.CreateUserToken(ctx, userRef, req.TokenName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -434,7 +434,7 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
resp := &csapitypes.CreateUserTokenResponse{ resp := &csapitypes.CreateUserTokenResponse{
Token: token, Token: token,
} }
if err := httpResponse(w, http.StatusCreated, resp); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, resp); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -455,11 +455,11 @@ func (h *DeleteUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
tokenName := vars["tokenname"] tokenName := vars["tokenname"]
err := h.ah.DeleteUserToken(ctx, userRef, tokenName) err := h.ah.DeleteUserToken(ctx, userRef, tokenName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -486,7 +486,7 @@ func (h *UserOrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
userRef := vars["userref"] userRef := vars["userref"]
userOrgs, err := h.ah.GetUserOrgs(ctx, userRef) userOrgs, err := h.ah.GetUserOrgs(ctx, userRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -496,7 +496,7 @@ func (h *UserOrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
res[i] = userOrgsResponse(userOrg) res[i] = userOrgsResponse(userOrg)
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -45,13 +45,13 @@ func (h *VariablesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, tree := query["tree"] _, tree := query["tree"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
variables, err := h.ah.GetVariables(ctx, parentType, parentRef, tree) variables, err := h.ah.GetVariables(ctx, parentType, parentRef, tree)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -73,11 +73,11 @@ func (h *VariablesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}) })
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, resVariables); err != nil { if err := util.HTTPResponse(w, http.StatusOK, resVariables); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -94,7 +94,7 @@ func NewCreateVariableHandler(logger *zap.Logger, ah *action.ActionHandler) *Cre
func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -102,7 +102,7 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
var variable *types.Variable var variable *types.Variable
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&variable); err != nil { if err := d.Decode(&variable); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -110,12 +110,12 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
variable.Parent.ID = parentRef variable.Parent.ID = parentRef
variable, err = h.ah.CreateVariable(ctx, variable) variable, err = h.ah.CreateVariable(ctx, variable)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, variable); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, variable); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -135,7 +135,7 @@ func (h *UpdateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
variableName := vars["variablename"] variableName := vars["variablename"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -143,7 +143,7 @@ func (h *UpdateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
var variable *types.Variable var variable *types.Variable
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&variable); err != nil { if err := d.Decode(&variable); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -155,12 +155,12 @@ func (h *UpdateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
Variable: variable, Variable: variable,
} }
variable, err = h.ah.UpdateVariable(ctx, areq) variable, err = h.ah.UpdateVariable(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, variable); err != nil { if err := util.HTTPResponse(w, http.StatusOK, variable); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -180,16 +180,16 @@ func (h *DeleteVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
variableName := vars["variablename"] variableName := vars["variablename"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
err = h.ah.DeleteVariable(ctx, parentType, parentRef, variableName) err = h.ah.DeleteVariable(ctx, parentType, parentRef, variableName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -1321,7 +1321,7 @@ func TestRemoteSource(t *testing.T) {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
expectedError := util.NewErrBadRequest(fmt.Errorf(`remotesource "rs01" already exists`)) expectedError := util.NewAPIError(util.ErrBadRequest, fmt.Errorf(`remotesource "rs01" already exists`))
_, err = cs.ah.CreateRemoteSource(ctx, rs) _, err = cs.ah.CreateRemoteSource(ctx, rs)
if err.Error() != expectedError.Error() { if err.Error() != expectedError.Error() {
t.Fatalf("expected err: %v, got err: %v", expectedError.Error(), err.Error()) t.Fatalf("expected err: %v, got err: %v", expectedError.Error(), err.Error())
@ -1410,7 +1410,7 @@ func TestRemoteSource(t *testing.T) {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
expectedError := util.NewErrBadRequest(fmt.Errorf(`remotesource "rs02" already exists`)) expectedError := util.NewAPIError(util.ErrBadRequest, fmt.Errorf(`remotesource "rs02" already exists`))
rs01.Name = "rs02" rs01.Name = "rs02"
req := &action.UpdateRemoteSourceRequest{ req := &action.UpdateRemoteSourceRequest{
RemoteSourceRef: "rs01", RemoteSourceRef: "rs01",

View File

@ -18,38 +18,11 @@ import (
"path" "path"
"agola.io/agola/internal/db" "agola.io/agola/internal/db"
"agola.io/agola/internal/util"
"agola.io/agola/services/configstore/types" "agola.io/agola/services/configstore/types"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
) )
func (r *ReadDB) ResolveConfigID(tx *db.Tx, configType types.ConfigType, ref string) (string, error) {
switch configType {
case types.ConfigTypeProjectGroup:
group, err := r.GetProjectGroup(tx, ref)
if err != nil {
return "", err
}
if group == nil {
return "", util.NewErrBadRequest(errors.Errorf("group with ref %q doesn't exists", ref))
}
return group.ID, nil
case types.ConfigTypeProject:
project, err := r.GetProject(tx, ref)
if err != nil {
return "", err
}
if project == nil {
return "", util.NewErrBadRequest(errors.Errorf("project with ref %q doesn't exists", ref))
}
return project.ID, nil
default:
return "", util.NewErrBadRequest(errors.Errorf("unknown config type %q", configType))
}
}
func (r *ReadDB) GetPath(tx *db.Tx, configType types.ConfigType, id string) (string, error) { func (r *ReadDB) GetPath(tx *db.Tx, configType types.ConfigType, id string) (string, error) {
var p string var p string
switch configType { switch configType {

View File

@ -25,8 +25,8 @@ import (
"agola.io/agola/internal/testutil" "agola.io/agola/internal/testutil"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/google/go-cmp/cmp"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
"github.com/google/go-cmp/cmp"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zaptest" "go.uber.org/zap/zaptest"
) )

View File

@ -15,10 +15,7 @@
package action package action
import ( import (
"net/http"
"agola.io/agola/internal/services/common" "agola.io/agola/internal/services/common"
"agola.io/agola/internal/util"
csclient "agola.io/agola/services/configstore/client" csclient "agola.io/agola/services/configstore/client"
rsclient "agola.io/agola/services/runservice/client" rsclient "agola.io/agola/services/runservice/client"
@ -46,20 +43,3 @@ func NewActionHandler(logger *zap.Logger, sd *common.TokenSigningData, configsto
webExposedURL: webExposedURL, webExposedURL: webExposedURL,
} }
} }
func ErrFromRemote(resp *http.Response, err error) error {
if err == nil {
return nil
}
if resp != nil {
switch resp.StatusCode {
case http.StatusBadRequest:
return util.NewErrBadRequest(err)
case http.StatusNotFound:
return util.NewErrNotExist(err)
}
}
return err
}

View File

@ -19,6 +19,7 @@ import (
scommon "agola.io/agola/internal/services/common" scommon "agola.io/agola/internal/services/common"
"agola.io/agola/internal/services/gateway/common" "agola.io/agola/internal/services/gateway/common"
"agola.io/agola/internal/util"
cstypes "agola.io/agola/services/configstore/types" cstypes "agola.io/agola/services/configstore/types"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
@ -35,9 +36,9 @@ func (h *ActionHandler) IsOrgOwner(ctx context.Context, orgID string) (bool, err
return false, nil return false, nil
} }
userOrgs, resp, err := h.configstoreClient.GetUserOrgs(ctx, userID) userOrgs, _, err := h.configstoreClient.GetUserOrgs(ctx, userID)
if err != nil { if err != nil {
return false, errors.Errorf("failed to get user orgs: %w", ErrFromRemote(resp, err)) return false, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user orgs: %w", err))
} }
for _, userOrg := range userOrgs { for _, userOrg := range userOrgs {
@ -70,9 +71,9 @@ func (h *ActionHandler) IsProjectOwner(ctx context.Context, ownerType cstypes.Co
} }
if ownerType == cstypes.ConfigTypeOrg { if ownerType == cstypes.ConfigTypeOrg {
userOrgs, resp, err := h.configstoreClient.GetUserOrgs(ctx, userID) userOrgs, _, err := h.configstoreClient.GetUserOrgs(ctx, userID)
if err != nil { if err != nil {
return false, errors.Errorf("failed to get user orgs: %w", ErrFromRemote(resp, err)) return false, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user orgs: %w", err))
} }
for _, userOrg := range userOrgs { for _, userOrg := range userOrgs {
@ -106,9 +107,9 @@ func (h *ActionHandler) IsProjectMember(ctx context.Context, ownerType cstypes.C
} }
if ownerType == cstypes.ConfigTypeOrg { if ownerType == cstypes.ConfigTypeOrg {
userOrgs, resp, err := h.configstoreClient.GetUserOrgs(ctx, userID) userOrgs, _, err := h.configstoreClient.GetUserOrgs(ctx, userID)
if err != nil { if err != nil {
return false, errors.Errorf("failed to get user orgs: %w", ErrFromRemote(resp, err)) return false, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user orgs: %w", err))
} }
for _, userOrg := range userOrgs { for _, userOrg := range userOrgs {
@ -127,16 +128,16 @@ func (h *ActionHandler) IsVariableOwner(ctx context.Context, parentType cstypes.
var ownerID string var ownerID string
switch parentType { switch parentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
pg, resp, err := h.configstoreClient.GetProjectGroup(ctx, parentRef) pg, _, err := h.configstoreClient.GetProjectGroup(ctx, parentRef)
if err != nil { if err != nil {
return false, errors.Errorf("failed to get project group %q: %w", parentRef, ErrFromRemote(resp, err)) return false, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project group %q: %w", parentRef, err))
} }
ownerType = pg.OwnerType ownerType = pg.OwnerType
ownerID = pg.OwnerID ownerID = pg.OwnerID
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
p, resp, err := h.configstoreClient.GetProject(ctx, parentRef) p, _, err := h.configstoreClient.GetProject(ctx, parentRef)
if err != nil { if err != nil {
return false, errors.Errorf("failed to get project %q: %w", parentRef, ErrFromRemote(resp, err)) return false, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", parentRef, err))
} }
ownerType = p.OwnerType ownerType = p.OwnerType
ownerID = p.OwnerID ownerID = p.OwnerID
@ -156,9 +157,9 @@ func (h *ActionHandler) CanGetRun(ctx context.Context, runGroup string) (bool, e
var ownerID string var ownerID string
switch groupType { switch groupType {
case scommon.GroupTypeProject: case scommon.GroupTypeProject:
p, resp, err := h.configstoreClient.GetProject(ctx, groupID) p, _, err := h.configstoreClient.GetProject(ctx, groupID)
if err != nil { if err != nil {
return false, ErrFromRemote(resp, err) return false, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
ownerType = p.OwnerType ownerType = p.OwnerType
ownerID = p.OwnerID ownerID = p.OwnerID
@ -193,9 +194,9 @@ func (h *ActionHandler) CanDoRunActions(ctx context.Context, runGroup string) (b
var ownerID string var ownerID string
switch groupType { switch groupType {
case scommon.GroupTypeProject: case scommon.GroupTypeProject:
p, resp, err := h.configstoreClient.GetProject(ctx, groupID) p, _, err := h.configstoreClient.GetProject(ctx, groupID)
if err != nil { if err != nil {
return false, ErrFromRemote(resp, err) return false, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
ownerType = p.OwnerType ownerType = p.OwnerType
ownerID = p.OwnerID ownerID = p.OwnerID

View File

@ -20,22 +20,23 @@ import (
"path" "path"
"agola.io/agola/internal/services/common" "agola.io/agola/internal/services/common"
"agola.io/agola/internal/util"
rstypes "agola.io/agola/services/runservice/types" rstypes "agola.io/agola/services/runservice/types"
) )
// GetBadge return a badge for a project branch // GetBadge return a badge for a project branch
// TODO(sgotti) also handle tags and PRs // TODO(sgotti) also handle tags and PRs
func (h *ActionHandler) GetBadge(ctx context.Context, projectRef, branch string) (string, error) { func (h *ActionHandler) GetBadge(ctx context.Context, projectRef, branch string) (string, error) {
project, resp, err := h.configstoreClient.GetProject(ctx, projectRef) project, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return "", ErrFromRemote(resp, err) return "", util.NewAPIError(util.KindFromRemoteError(err), err)
} }
// if branch is empty we get the latest run for every branch. // if branch is empty we get the latest run for every branch.
group := path.Join("/", string(common.GroupTypeProject), project.ID, string(common.GroupTypeBranch), url.PathEscape(branch)) group := path.Join("/", string(common.GroupTypeProject), project.ID, string(common.GroupTypeBranch), url.PathEscape(branch))
runResp, resp, err := h.runserviceClient.GetGroupLastRun(ctx, group, nil) runResp, _, err := h.runserviceClient.GetGroupLastRun(ctx, group, nil)
if err != nil { if err != nil {
return "", ErrFromRemote(resp, err) return "", util.NewAPIError(util.KindFromRemoteError(err), err)
} }
if len(runResp.Runs) == 0 { if len(runResp.Runs) == 0 {
return badgeUnknown, nil return badgeUnknown, nil

View File

@ -25,9 +25,9 @@ import (
) )
func (h *ActionHandler) GetOrg(ctx context.Context, orgRef string) (*cstypes.Organization, error) { func (h *ActionHandler) GetOrg(ctx context.Context, orgRef string) (*cstypes.Organization, error) {
org, resp, err := h.configstoreClient.GetOrg(ctx, orgRef) org, _, err := h.configstoreClient.GetOrg(ctx, orgRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return org, nil return org, nil
} }
@ -39,9 +39,9 @@ type GetOrgsRequest struct {
} }
func (h *ActionHandler) GetOrgs(ctx context.Context, req *GetOrgsRequest) ([]*cstypes.Organization, error) { func (h *ActionHandler) GetOrgs(ctx context.Context, req *GetOrgsRequest) ([]*cstypes.Organization, error) {
orgs, resp, err := h.configstoreClient.GetOrgs(ctx, req.Start, req.Limit, req.Asc) orgs, _, err := h.configstoreClient.GetOrgs(ctx, req.Start, req.Limit, req.Asc)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return orgs, nil return orgs, nil
} }
@ -57,14 +57,14 @@ type OrgMemberResponse struct {
} }
func (h *ActionHandler) GetOrgMembers(ctx context.Context, orgRef string) (*OrgMembersResponse, error) { func (h *ActionHandler) GetOrgMembers(ctx context.Context, orgRef string) (*OrgMembersResponse, error) {
org, resp, err := h.configstoreClient.GetOrg(ctx, orgRef) org, _, err := h.configstoreClient.GetOrg(ctx, orgRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
orgMembers, resp, err := h.configstoreClient.GetOrgMembers(ctx, orgRef) orgMembers, _, err := h.configstoreClient.GetOrgMembers(ctx, orgRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
res := &OrgMembersResponse{ res := &OrgMembersResponse{
@ -93,10 +93,10 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, req *CreateOrgRequest) (*
} }
if req.Name == "" { if req.Name == "" {
return nil, util.NewErrBadRequest(errors.Errorf("organization name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("organization name required"))
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid organization name %q", req.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid organization name %q", req.Name))
} }
org := &cstypes.Organization{ org := &cstypes.Organization{
@ -108,9 +108,9 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, req *CreateOrgRequest) (*
} }
h.log.Infof("creating organization") h.log.Infof("creating organization")
org, resp, err := h.configstoreClient.CreateOrg(ctx, org) org, _, err := h.configstoreClient.CreateOrg(ctx, org)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create organization: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create organization: %w", err))
} }
h.log.Infof("organization %s created, ID: %s", org.Name, org.ID) h.log.Infof("organization %s created, ID: %s", org.Name, org.ID)
@ -118,9 +118,9 @@ func (h *ActionHandler) CreateOrg(ctx context.Context, req *CreateOrgRequest) (*
} }
func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error { func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
org, resp, err := h.configstoreClient.GetOrg(ctx, orgRef) org, _, err := h.configstoreClient.GetOrg(ctx, orgRef)
if err != nil { if err != nil {
return ErrFromRemote(resp, err) return util.NewAPIError(util.KindFromRemoteError(err), err)
} }
isOrgOwner, err := h.IsOrgOwner(ctx, org.ID) isOrgOwner, err := h.IsOrgOwner(ctx, org.ID)
@ -128,12 +128,11 @@ func (h *ActionHandler) DeleteOrg(ctx context.Context, orgRef string) error {
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isOrgOwner { if !isOrgOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
resp, err = h.configstoreClient.DeleteOrg(ctx, orgRef) if _, err := h.configstoreClient.DeleteOrg(ctx, orgRef); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to delete org: %w", err))
return errors.Errorf("failed to delete org: %w", ErrFromRemote(resp, err))
} }
return nil return nil
} }
@ -145,13 +144,13 @@ type AddOrgMemberResponse struct {
} }
func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string, role cstypes.MemberRole) (*AddOrgMemberResponse, error) { func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string, role cstypes.MemberRole) (*AddOrgMemberResponse, error) {
org, resp, err := h.configstoreClient.GetOrg(ctx, orgRef) org, _, err := h.configstoreClient.GetOrg(ctx, orgRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
isOrgOwner, err := h.IsOrgOwner(ctx, org.ID) isOrgOwner, err := h.IsOrgOwner(ctx, org.ID)
@ -159,12 +158,12 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isOrgOwner { if !isOrgOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
orgmember, resp, err := h.configstoreClient.AddOrgMember(ctx, orgRef, userRef, role) orgmember, _, err := h.configstoreClient.AddOrgMember(ctx, orgRef, userRef, role)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to add/update organization member: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to add/update organization member: %w", err))
} }
return &AddOrgMemberResponse{ return &AddOrgMemberResponse{
@ -175,9 +174,9 @@ func (h *ActionHandler) AddOrgMember(ctx context.Context, orgRef, userRef string
} }
func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef string) error { func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef string) error {
org, resp, err := h.configstoreClient.GetOrg(ctx, orgRef) org, _, err := h.configstoreClient.GetOrg(ctx, orgRef)
if err != nil { if err != nil {
return ErrFromRemote(resp, err) return util.NewAPIError(util.KindFromRemoteError(err), err)
} }
isOrgOwner, err := h.IsOrgOwner(ctx, org.ID) isOrgOwner, err := h.IsOrgOwner(ctx, org.ID)
@ -185,12 +184,11 @@ func (h *ActionHandler) RemoveOrgMember(ctx context.Context, orgRef, userRef str
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isOrgOwner { if !isOrgOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
resp, err = h.configstoreClient.RemoveOrgMember(ctx, orgRef, userRef) if _, err = h.configstoreClient.RemoveOrgMember(ctx, orgRef, userRef); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to remove organization member: %w", err))
return errors.Errorf("failed to remove organization member: %w", ErrFromRemote(resp, err))
} }
return nil return nil

View File

@ -17,7 +17,6 @@ package action
import ( import (
"context" "context"
"fmt" "fmt"
"net/http"
"net/url" "net/url"
"path" "path"
@ -32,9 +31,9 @@ import (
) )
func (h *ActionHandler) GetProject(ctx context.Context, projectRef string) (*csapitypes.Project, error) { func (h *ActionHandler) GetProject(ctx context.Context, projectRef string) (*csapitypes.Project, error) {
project, resp, err := h.configstoreClient.GetProject(ctx, projectRef) project, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, err
} }
isProjectMember, err := h.IsProjectMember(ctx, project.OwnerType, project.OwnerID) isProjectMember, err := h.IsProjectMember(ctx, project.OwnerType, project.OwnerID)
@ -45,7 +44,7 @@ func (h *ActionHandler) GetProject(ctx context.Context, projectRef string) (*csa
return project, nil return project, nil
} }
if !isProjectMember { if !isProjectMember {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
return project, nil return project, nil
@ -64,9 +63,9 @@ type CreateProjectRequest struct {
func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectRequest) (*csapitypes.Project, error) { func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectRequest) (*csapitypes.Project, error) {
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
user, resp, err := h.configstoreClient.GetUser(ctx, curUserID) user, _, err := h.configstoreClient.GetUser(ctx, curUserID)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get user %q: %w", curUserID, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", curUserID, err))
} }
parentRef := req.ParentRef parentRef := req.ParentRef
if parentRef == "" { if parentRef == "" {
@ -74,9 +73,9 @@ func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectReq
parentRef = path.Join("user", user.Name) parentRef = path.Join("user", user.Name)
} }
pg, resp, err := h.configstoreClient.GetProjectGroup(ctx, parentRef) pg, _, err := h.configstoreClient.GetProjectGroup(ctx, parentRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get project group %q: %w", parentRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project group %q: %w", parentRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, pg.OwnerType, pg.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, pg.OwnerType, pg.OwnerID)
@ -84,32 +83,31 @@ func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectReq
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid project name %q", req.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid project name %q", req.Name))
} }
if req.RemoteSourceName == "" { if req.RemoteSourceName == "" {
return nil, util.NewErrBadRequest(errors.Errorf("empty remote source name")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty remote source name"))
} }
if req.RepoPath == "" { if req.RepoPath == "" {
return nil, util.NewErrBadRequest(errors.Errorf("empty remote repo path")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty remote repo path"))
} }
projectPath := path.Join(pg.Path, req.Name) projectPath := path.Join(pg.Path, req.Name)
_, resp, err = h.configstoreClient.GetProject(ctx, projectPath) if _, _, err = h.configstoreClient.GetProject(ctx, projectPath); err != nil {
if err != nil { if !util.RemoteErrorIs(err, util.ErrNotExist) {
if resp != nil && resp.StatusCode != http.StatusNotFound { return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", req.Name, err))
return nil, errors.Errorf("failed to get project %q: %w", req.Name, ErrFromRemote(resp, err))
} }
} else { } else {
return nil, util.NewErrBadRequest(errors.Errorf("project %q already exists", projectPath)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("project %q already exists", projectPath))
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, err))
} }
var la *cstypes.LinkedAccount var la *cstypes.LinkedAccount
for _, v := range user.LinkedAccounts { for _, v := range user.LinkedAccounts {
@ -156,25 +154,24 @@ func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectReq
} }
h.log.Infof("creating project") h.log.Infof("creating project")
rp, resp, err := h.configstoreClient.CreateProject(ctx, p) rp, _, err := h.configstoreClient.CreateProject(ctx, p)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create project: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create project: %w", err))
} }
h.log.Infof("project %s created, ID: %s", rp.Name, rp.ID) h.log.Infof("project %s created, ID: %s", rp.Name, rp.ID)
if serr := h.setupGitSourceRepo(ctx, rs, user, la, rp); serr != nil { if serr := h.setupGitSourceRepo(ctx, rs, user, la, rp); serr != nil {
var err error var err error
h.log.Errorf("failed to setup git source repo, trying to cleanup: %+v", ErrFromRemote(resp, err)) h.log.Errorf("failed to setup git source repo, trying to cleanup: %+v", err)
// try to cleanup gitsource configs and remove project // try to cleanup gitsource configs and remove project
// we'll log but ignore errors // we'll log but ignore errors
h.log.Infof("deleting project with ID: %q", rp.ID) h.log.Infof("deleting project with ID: %q", rp.ID)
resp, err := h.configstoreClient.DeleteProject(ctx, rp.ID) if _, err := h.configstoreClient.DeleteProject(ctx, rp.ID); err != nil {
if err != nil { h.log.Errorf("failed to delete project: %+v", err)
h.log.Errorf("failed to delete project: %+v", ErrFromRemote(resp, err))
} }
h.log.Infof("cleanup git source repo") h.log.Infof("cleanup git source repo")
if err := h.cleanupGitSourceRepo(ctx, rs, user, la, rp); err != nil { if err := h.cleanupGitSourceRepo(ctx, rs, user, la, rp); err != nil {
h.log.Errorf("failed to cleanup git source repo: %+v", ErrFromRemote(resp, err)) h.log.Errorf("failed to cleanup git source repo: %+v", err)
} }
return nil, errors.Errorf("failed to setup git source repo: %w", serr) return nil, errors.Errorf("failed to setup git source repo: %w", serr)
} }
@ -191,9 +188,9 @@ type UpdateProjectRequest struct {
} }
func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, req *UpdateProjectRequest) (*csapitypes.Project, error) { func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, req *UpdateProjectRequest) (*csapitypes.Project, error) {
p, resp, err := h.configstoreClient.GetProject(ctx, projectRef) p, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get project %q: %w", projectRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", projectRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID)
@ -201,7 +198,7 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, re
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if req.Name != nil { if req.Name != nil {
@ -218,9 +215,9 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, re
} }
h.log.Infof("updating project") h.log.Infof("updating project")
rp, resp, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project) rp, _, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to update project: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to update project: %w", err))
} }
h.log.Infof("project %s updated, ID: %s", p.Name, p.ID) h.log.Infof("project %s updated, ID: %s", p.Name, p.ID)
@ -230,14 +227,14 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, re
func (h *ActionHandler) ProjectUpdateRepoLinkedAccount(ctx context.Context, projectRef string) (*csapitypes.Project, error) { func (h *ActionHandler) ProjectUpdateRepoLinkedAccount(ctx context.Context, projectRef string) (*csapitypes.Project, error) {
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
user, resp, err := h.configstoreClient.GetUser(ctx, curUserID) user, _, err := h.configstoreClient.GetUser(ctx, curUserID)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get user %q: %w", curUserID, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", curUserID, err))
} }
p, resp, err := h.configstoreClient.GetProject(ctx, projectRef) p, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get project %q: %w", projectRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", projectRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID)
@ -245,12 +242,12 @@ func (h *ActionHandler) ProjectUpdateRepoLinkedAccount(ctx context.Context, proj
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, p.RemoteSourceID) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, p.RemoteSourceID)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", p.RemoteSourceID, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", p.RemoteSourceID, err))
} }
var la *cstypes.LinkedAccount var la *cstypes.LinkedAccount
for _, v := range user.LinkedAccounts { for _, v := range user.LinkedAccounts {
@ -260,7 +257,7 @@ func (h *ActionHandler) ProjectUpdateRepoLinkedAccount(ctx context.Context, proj
} }
} }
if la == nil { if la == nil {
return nil, util.NewErrBadRequest(errors.Errorf("user doesn't have a linked account for remote source %q", rs.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user doesn't have a linked account for remote source %q", rs.Name))
} }
gitsource, err := h.GetGitSource(ctx, rs, user.Name, la) gitsource, err := h.GetGitSource(ctx, rs, user.Name, la)
@ -277,9 +274,9 @@ func (h *ActionHandler) ProjectUpdateRepoLinkedAccount(ctx context.Context, proj
p.LinkedAccountID = la.ID p.LinkedAccountID = la.ID
h.log.Infof("updating project") h.log.Infof("updating project")
rp, resp, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project) rp, _, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to update project: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to update project: %w", err))
} }
h.log.Infof("project %s updated, ID: %s", p.Name, p.ID) h.log.Infof("project %s updated, ID: %s", p.Name, p.ID)
@ -364,9 +361,9 @@ func (h *ActionHandler) genWebhookURL(project *csapitypes.Project) (string, erro
} }
func (h *ActionHandler) ReconfigProject(ctx context.Context, projectRef string) error { func (h *ActionHandler) ReconfigProject(ctx context.Context, projectRef string) error {
p, resp, err := h.configstoreClient.GetProject(ctx, projectRef) p, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get project %q: %w", projectRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", projectRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID)
@ -374,7 +371,7 @@ func (h *ActionHandler) ReconfigProject(ctx context.Context, projectRef string)
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
user, rs, la, err := h.getRemoteRepoAccessData(ctx, p.LinkedAccountID) user, rs, la, err := h.getRemoteRepoAccessData(ctx, p.LinkedAccountID)
@ -388,9 +385,9 @@ func (h *ActionHandler) ReconfigProject(ctx context.Context, projectRef string)
} }
func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) error { func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) error {
p, resp, err := h.configstoreClient.GetProject(ctx, projectRef) p, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get project %q: %w", projectRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", projectRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID)
@ -398,7 +395,7 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
// get data needed for repo cleanup // get data needed for repo cleanup
@ -411,9 +408,8 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
} }
h.log.Infof("deleting project with ID: %q", p.ID) h.log.Infof("deleting project with ID: %q", p.ID)
resp, err = h.configstoreClient.DeleteProject(ctx, projectRef) if _, err = h.configstoreClient.DeleteProject(ctx, projectRef); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), err)
return ErrFromRemote(resp, err)
} }
// try to cleanup gitsource configs // try to cleanup gitsource configs
@ -421,7 +417,7 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
if canDoRepCleanup { if canDoRepCleanup {
h.log.Infof("cleanup git source repo") h.log.Infof("cleanup git source repo")
if err := h.cleanupGitSourceRepo(ctx, rs, user, la, p); err != nil { if err := h.cleanupGitSourceRepo(ctx, rs, user, la, p); err != nil {
h.log.Errorf("failed to cleanup git source repo: %+v", ErrFromRemote(resp, err)) h.log.Errorf("failed to cleanup git source repo: %+v", err)
} }
} }
@ -431,14 +427,14 @@ func (h *ActionHandler) DeleteProject(ctx context.Context, projectRef string) er
func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch, tag, refName, commitSHA string) error { func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch, tag, refName, commitSHA string) error {
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
user, resp, err := h.configstoreClient.GetUser(ctx, curUserID) user, _, err := h.configstoreClient.GetUser(ctx, curUserID)
if err != nil { if err != nil {
return errors.Errorf("failed to get user %q: %w", curUserID, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", curUserID, err))
} }
p, resp, err := h.configstoreClient.GetProject(ctx, projectRef) p, _, err := h.configstoreClient.GetProject(ctx, projectRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get project %q: %w", projectRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", projectRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID)
@ -446,12 +442,12 @@ func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, p.RemoteSourceID) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, p.RemoteSourceID)
if err != nil { if err != nil {
return errors.Errorf("failed to get remote source %q: %w", p.RemoteSourceID, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", p.RemoteSourceID, err))
} }
var la *cstypes.LinkedAccount var la *cstypes.LinkedAccount
for _, v := range user.LinkedAccounts { for _, v := range user.LinkedAccounts {
@ -461,7 +457,7 @@ func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch
} }
} }
if la == nil { if la == nil {
return util.NewErrBadRequest(errors.Errorf("user doesn't have a linked account for remote source %q", rs.Name)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user doesn't have a linked account for remote source %q", rs.Name))
} }
gitSource, err := h.GetGitSource(ctx, rs, user.Name, la) gitSource, err := h.GetGitSource(ctx, rs, user.Name, la)
@ -486,10 +482,10 @@ func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch
set++ set++
} }
if set == 0 { if set == 0 {
return util.NewErrBadRequest(errors.Errorf("one of branch, tag or ref is required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("one of branch, tag or ref is required"))
} }
if set > 1 { if set > 1 {
return util.NewErrBadRequest(errors.Errorf("only one of branch, tag or ref can be provided")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("only one of branch, tag or ref can be provided"))
} }
var refType types.RunRefType var refType types.RunRefType
@ -508,7 +504,7 @@ func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch
gitRefType, name, err := gitSource.RefType(refName) gitRefType, name, err := gitSource.RefType(refName)
if err != nil { if err != nil {
return util.NewErrBadRequest(errors.Errorf("failed to get refType for ref %q: %w", refName, err)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("failed to get refType for ref %q: %w", refName, err))
} }
ref, err := gitSource.GetRef(p.RepositoryPath, refName) ref, err := gitSource.GetRef(p.RepositoryPath, refName)
if err != nil { if err != nil {
@ -587,9 +583,9 @@ func (h *ActionHandler) ProjectCreateRun(ctx context.Context, projectRef, branch
} }
func (h *ActionHandler) getRemoteRepoAccessData(ctx context.Context, linkedAccountID string) (*cstypes.User, *cstypes.RemoteSource, *cstypes.LinkedAccount, error) { func (h *ActionHandler) getRemoteRepoAccessData(ctx context.Context, linkedAccountID string) (*cstypes.User, *cstypes.RemoteSource, *cstypes.LinkedAccount, error) {
user, resp, err := h.configstoreClient.GetUserByLinkedAccount(ctx, linkedAccountID) user, _, err := h.configstoreClient.GetUserByLinkedAccount(ctx, linkedAccountID)
if err != nil { if err != nil {
return nil, nil, nil, errors.Errorf("failed to get user with linked account id %q: %w", linkedAccountID, ErrFromRemote(resp, err)) return nil, nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user with linked account id %q: %w", linkedAccountID, err))
} }
la := user.LinkedAccounts[linkedAccountID] la := user.LinkedAccounts[linkedAccountID]
@ -597,9 +593,9 @@ func (h *ActionHandler) getRemoteRepoAccessData(ctx context.Context, linkedAccou
return nil, nil, nil, errors.Errorf("linked account %q in user %q doesn't exist", linkedAccountID, user.Name) return nil, nil, nil, errors.Errorf("linked account %q in user %q doesn't exist", linkedAccountID, user.Name)
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID)
if err != nil { if err != nil {
return nil, nil, nil, errors.Errorf("failed to get remote source %q: %w", la.RemoteSourceID, ErrFromRemote(resp, err)) return nil, nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", la.RemoteSourceID, err))
} }
return user, rs, la, nil return user, rs, la, nil

View File

@ -26,25 +26,25 @@ import (
) )
func (h *ActionHandler) GetProjectGroup(ctx context.Context, projectGroupRef string) (*csapitypes.ProjectGroup, error) { func (h *ActionHandler) GetProjectGroup(ctx context.Context, projectGroupRef string) (*csapitypes.ProjectGroup, error) {
projectGroup, resp, err := h.configstoreClient.GetProjectGroup(ctx, projectGroupRef) projectGroup, _, err := h.configstoreClient.GetProjectGroup(ctx, projectGroupRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return projectGroup, nil return projectGroup, nil
} }
func (h *ActionHandler) GetProjectGroupSubgroups(ctx context.Context, projectGroupRef string) ([]*csapitypes.ProjectGroup, error) { func (h *ActionHandler) GetProjectGroupSubgroups(ctx context.Context, projectGroupRef string) ([]*csapitypes.ProjectGroup, error) {
projectGroups, resp, err := h.configstoreClient.GetProjectGroupSubgroups(ctx, projectGroupRef) projectGroups, _, err := h.configstoreClient.GetProjectGroupSubgroups(ctx, projectGroupRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return projectGroups, nil return projectGroups, nil
} }
func (h *ActionHandler) GetProjectGroupProjects(ctx context.Context, projectGroupRef string) ([]*csapitypes.Project, error) { func (h *ActionHandler) GetProjectGroupProjects(ctx context.Context, projectGroupRef string) ([]*csapitypes.Project, error) {
projects, resp, err := h.configstoreClient.GetProjectGroupProjects(ctx, projectGroupRef) projects, _, err := h.configstoreClient.GetProjectGroupProjects(ctx, projectGroupRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return projects, nil return projects, nil
} }
@ -58,12 +58,12 @@ type CreateProjectGroupRequest struct {
func (h *ActionHandler) CreateProjectGroup(ctx context.Context, req *CreateProjectGroupRequest) (*csapitypes.ProjectGroup, error) { func (h *ActionHandler) CreateProjectGroup(ctx context.Context, req *CreateProjectGroupRequest) (*csapitypes.ProjectGroup, error) {
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid projectGroup name %q", req.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid projectGroup name %q", req.Name))
} }
pg, resp, err := h.configstoreClient.GetProjectGroup(ctx, req.ParentRef) pg, _, err := h.configstoreClient.GetProjectGroup(ctx, req.ParentRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get project group %q: %w", req.ParentRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project group %q: %w", req.ParentRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, pg.OwnerType, pg.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, pg.OwnerType, pg.OwnerID)
@ -71,12 +71,12 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, req *CreateProje
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
user, resp, err := h.configstoreClient.GetUser(ctx, req.CurrentUserID) user, _, err := h.configstoreClient.GetUser(ctx, req.CurrentUserID)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get user %q: %w", req.CurrentUserID, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", req.CurrentUserID, err))
} }
parentRef := req.ParentRef parentRef := req.ParentRef
@ -95,9 +95,9 @@ func (h *ActionHandler) CreateProjectGroup(ctx context.Context, req *CreateProje
} }
h.log.Infof("creating projectGroup") h.log.Infof("creating projectGroup")
rp, resp, err := h.configstoreClient.CreateProjectGroup(ctx, p) rp, _, err := h.configstoreClient.CreateProjectGroup(ctx, p)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create projectGroup: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create projectGroup: %w", err))
} }
h.log.Infof("projectGroup %s created, ID: %s", rp.Name, rp.ID) h.log.Infof("projectGroup %s created, ID: %s", rp.Name, rp.ID)
@ -112,9 +112,9 @@ type UpdateProjectGroupRequest struct {
} }
func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, projectGroupRef string, req *UpdateProjectGroupRequest) (*csapitypes.ProjectGroup, error) { func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, projectGroupRef string, req *UpdateProjectGroupRequest) (*csapitypes.ProjectGroup, error) {
pg, resp, err := h.configstoreClient.GetProjectGroup(ctx, projectGroupRef) pg, _, err := h.configstoreClient.GetProjectGroup(ctx, projectGroupRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get project group %q: %w", projectGroupRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project group %q: %w", projectGroupRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, pg.OwnerType, pg.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, pg.OwnerType, pg.OwnerID)
@ -122,7 +122,7 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, projectGroupRef
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if req.Name != nil { if req.Name != nil {
@ -136,9 +136,9 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, projectGroupRef
} }
h.log.Infof("updating project group") h.log.Infof("updating project group")
rp, resp, err := h.configstoreClient.UpdateProjectGroup(ctx, pg.ID, pg.ProjectGroup) rp, _, err := h.configstoreClient.UpdateProjectGroup(ctx, pg.ID, pg.ProjectGroup)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to update project group: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to update project group: %w", err))
} }
h.log.Infof("project group %q updated, ID: %s", pg.Name, pg.ID) h.log.Infof("project group %q updated, ID: %s", pg.Name, pg.ID)
@ -146,9 +146,9 @@ func (h *ActionHandler) UpdateProjectGroup(ctx context.Context, projectGroupRef
} }
func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectRef string) error { func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectRef string) error {
p, resp, err := h.configstoreClient.GetProjectGroup(ctx, projectRef) p, _, err := h.configstoreClient.GetProjectGroup(ctx, projectRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get project %q: %w", projectRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q: %w", projectRef, err))
} }
isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID) isProjectOwner, err := h.IsProjectOwner(ctx, p.OwnerType, p.OwnerID)
@ -156,12 +156,11 @@ func (h *ActionHandler) DeleteProjectGroup(ctx context.Context, projectRef strin
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isProjectOwner { if !isProjectOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
resp, err = h.configstoreClient.DeleteProjectGroup(ctx, projectRef) if _, err = h.configstoreClient.DeleteProjectGroup(ctx, projectRef); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), err)
return ErrFromRemote(resp, err)
} }
return nil return nil
} }

View File

@ -25,9 +25,9 @@ import (
) )
func (h *ActionHandler) GetRemoteSource(ctx context.Context, rsRef string) (*cstypes.RemoteSource, error) { func (h *ActionHandler) GetRemoteSource(ctx context.Context, rsRef string) (*cstypes.RemoteSource, error) {
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, rsRef) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, rsRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, err
} }
return rs, nil return rs, nil
} }
@ -39,9 +39,9 @@ type GetRemoteSourcesRequest struct {
} }
func (h *ActionHandler) GetRemoteSources(ctx context.Context, req *GetRemoteSourcesRequest) ([]*cstypes.RemoteSource, error) { func (h *ActionHandler) GetRemoteSources(ctx context.Context, req *GetRemoteSourcesRequest) ([]*cstypes.RemoteSource, error) {
remoteSources, resp, err := h.configstoreClient.GetRemoteSources(ctx, req.Start, req.Limit, req.Asc) remoteSources, _, err := h.configstoreClient.GetRemoteSources(ctx, req.Start, req.Limit, req.Asc)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, err
} }
return remoteSources, nil return remoteSources, nil
} }
@ -66,33 +66,33 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemot
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid remotesource name %q", req.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid remotesource name %q", req.Name))
} }
if req.Name == "" { if req.Name == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource name required"))
} }
if req.APIURL == "" { if req.APIURL == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource api url required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource api url required"))
} }
if req.Type == "" { if req.Type == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource type required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource type required"))
} }
if req.AuthType == "" { if req.AuthType == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource auth type required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource auth type required"))
} }
// validate if the remote source type supports the required auth type // validate if the remote source type supports the required auth type
if !cstypes.SourceSupportsAuthType(cstypes.RemoteSourceType(req.Type), cstypes.RemoteSourceAuthType(req.AuthType)) { if !cstypes.SourceSupportsAuthType(cstypes.RemoteSourceType(req.Type), cstypes.RemoteSourceAuthType(req.AuthType)) {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource type %q doesn't support auth type %q", req.Type, req.AuthType)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource type %q doesn't support auth type %q", req.Type, req.AuthType))
} }
if req.AuthType == string(cstypes.RemoteSourceAuthTypeOauth2) { if req.AuthType == string(cstypes.RemoteSourceAuthTypeOauth2) {
if req.Oauth2ClientID == "" { if req.Oauth2ClientID == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource oauth2 clientid required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource oauth2 clientid required"))
} }
if req.Oauth2ClientSecret == "" { if req.Oauth2ClientSecret == "" {
return nil, util.NewErrBadRequest(errors.Errorf("remotesource oauth2 client secret required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remotesource oauth2 client secret required"))
} }
} }
@ -111,9 +111,9 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemot
} }
h.log.Infof("creating remotesource") h.log.Infof("creating remotesource")
rs, resp, err := h.configstoreClient.CreateRemoteSource(ctx, rs) rs, _, err := h.configstoreClient.CreateRemoteSource(ctx, rs)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create remotesource: %w", ErrFromRemote(resp, err)) return nil, errors.Errorf("failed to create remotesource: %w", err)
} }
h.log.Infof("remotesource %s created, ID: %s", rs.Name, rs.ID) h.log.Infof("remotesource %s created, ID: %s", rs.Name, rs.ID)
@ -139,9 +139,9 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
return nil, errors.Errorf("user not admin") return nil, errors.Errorf("user not admin")
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceRef) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, err
} }
if req.Name != nil { if req.Name != nil {
@ -173,9 +173,9 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
} }
h.log.Infof("updating remotesource") h.log.Infof("updating remotesource")
rs, resp, err = h.configstoreClient.UpdateRemoteSource(ctx, req.RemoteSourceRef, rs) rs, _, err = h.configstoreClient.UpdateRemoteSource(ctx, req.RemoteSourceRef, rs)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to update remotesource: %w", ErrFromRemote(resp, err)) return nil, errors.Errorf("failed to update remotesource: %w", err)
} }
h.log.Infof("remotesource %s updated", rs.Name) h.log.Infof("remotesource %s updated", rs.Name)
@ -187,9 +187,8 @@ func (h *ActionHandler) DeleteRemoteSource(ctx context.Context, rsRef string) er
return errors.Errorf("user not admin") return errors.Errorf("user not admin")
} }
resp, err := h.configstoreClient.DeleteRemoteSource(ctx, rsRef) if _, err := h.configstoreClient.DeleteRemoteSource(ctx, rsRef); err != nil {
if err != nil { return errors.Errorf("failed to delete remote source: %w", err)
return errors.Errorf("failed to delete remote source: %w", ErrFromRemote(resp, err))
} }
return nil return nil
} }

View File

@ -74,16 +74,16 @@ var (
) )
func (h *ActionHandler) GetRun(ctx context.Context, runID string) (*rsapitypes.RunResponse, error) { func (h *ActionHandler) GetRun(ctx context.Context, runID string) (*rsapitypes.RunResponse, error) {
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID, nil) runResp, _, err := h.runserviceClient.GetRun(ctx, runID, nil)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
canGetRun, err := h.CanGetRun(ctx, runResp.RunConfig.Group) canGetRun, err := h.CanGetRun(ctx, runResp.RunConfig.Group)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to determine permissions: %w", err) return nil, errors.Errorf("failed to determine permissions: %w", err)
} }
if !canGetRun { if !canGetRun {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
return runResp, nil return runResp, nil
@ -106,13 +106,13 @@ func (h *ActionHandler) GetRuns(ctx context.Context, req *GetRunsRequest) (*rsap
return nil, errors.Errorf("failed to determine permissions: %w", err) return nil, errors.Errorf("failed to determine permissions: %w", err)
} }
if !canGetRun { if !canGetRun {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
groups := []string{req.Group} groups := []string{req.Group}
runsResp, resp, err := h.runserviceClient.GetRuns(ctx, req.PhaseFilter, req.ResultFilter, groups, req.LastRun, req.ChangeGroups, req.StartRunID, req.Limit, req.Asc) runsResp, _, err := h.runserviceClient.GetRuns(ctx, req.PhaseFilter, req.ResultFilter, groups, req.LastRun, req.ChangeGroups, req.StartRunID, req.Limit, req.Asc)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return runsResp, nil return runsResp, nil
@ -127,21 +127,21 @@ type GetLogsRequest struct {
} }
func (h *ActionHandler) GetLogs(ctx context.Context, req *GetLogsRequest) (*http.Response, error) { func (h *ActionHandler) GetLogs(ctx context.Context, req *GetLogsRequest) (*http.Response, error) {
runResp, resp, err := h.runserviceClient.GetRun(ctx, req.RunID, nil) runResp, _, err := h.runserviceClient.GetRun(ctx, req.RunID, nil)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
canGetRun, err := h.CanGetRun(ctx, runResp.RunConfig.Group) canGetRun, err := h.CanGetRun(ctx, runResp.RunConfig.Group)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to determine permissions: %w", err) return nil, errors.Errorf("failed to determine permissions: %w", err)
} }
if !canGetRun { if !canGetRun {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
resp, err = h.runserviceClient.GetLogs(ctx, req.RunID, req.TaskID, req.Setup, req.Step, req.Follow) resp, err := h.runserviceClient.GetLogs(ctx, req.RunID, req.TaskID, req.Setup, req.Step, req.Follow)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return resp, nil return resp, nil
@ -155,21 +155,20 @@ type DeleteLogsRequest struct {
} }
func (h *ActionHandler) DeleteLogs(ctx context.Context, req *DeleteLogsRequest) error { func (h *ActionHandler) DeleteLogs(ctx context.Context, req *DeleteLogsRequest) error {
runResp, resp, err := h.runserviceClient.GetRun(ctx, req.RunID, nil) runResp, _, err := h.runserviceClient.GetRun(ctx, req.RunID, nil)
if err != nil { if err != nil {
return ErrFromRemote(resp, err) return util.NewAPIError(util.KindFromRemoteError(err), err)
} }
canDoRunActions, err := h.CanDoRunActions(ctx, runResp.RunConfig.Group) canDoRunActions, err := h.CanDoRunActions(ctx, runResp.RunConfig.Group)
if err != nil { if err != nil {
return errors.Errorf("failed to determine permissions: %w", err) return errors.Errorf("failed to determine permissions: %w", err)
} }
if !canDoRunActions { if !canDoRunActions {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
resp, err = h.runserviceClient.DeleteLogs(ctx, req.RunID, req.TaskID, req.Setup, req.Step) if _, err = h.runserviceClient.DeleteLogs(ctx, req.RunID, req.TaskID, req.Setup, req.Step); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), err)
return ErrFromRemote(resp, err)
} }
return nil return nil
@ -192,16 +191,16 @@ type RunActionsRequest struct {
} }
func (h *ActionHandler) RunAction(ctx context.Context, req *RunActionsRequest) (*rsapitypes.RunResponse, error) { func (h *ActionHandler) RunAction(ctx context.Context, req *RunActionsRequest) (*rsapitypes.RunResponse, error) {
runResp, resp, err := h.runserviceClient.GetRun(ctx, req.RunID, nil) runResp, _, err := h.runserviceClient.GetRun(ctx, req.RunID, nil)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
canGetRun, err := h.CanDoRunActions(ctx, runResp.RunConfig.Group) canGetRun, err := h.CanDoRunActions(ctx, runResp.RunConfig.Group)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to determine permissions: %w", err) return nil, errors.Errorf("failed to determine permissions: %w", err)
} }
if !canGetRun { if !canGetRun {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
switch req.ActionType { switch req.ActionType {
@ -211,9 +210,9 @@ func (h *ActionHandler) RunAction(ctx context.Context, req *RunActionsRequest) (
FromStart: req.FromStart, FromStart: req.FromStart,
} }
runResp, resp, err = h.runserviceClient.CreateRun(ctx, rsreq) runResp, _, err = h.runserviceClient.CreateRun(ctx, rsreq)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
case RunActionTypeCancel: case RunActionTypeCancel:
@ -222,9 +221,8 @@ func (h *ActionHandler) RunAction(ctx context.Context, req *RunActionsRequest) (
Phase: rstypes.RunPhaseCancelled, Phase: rstypes.RunPhaseCancelled,
} }
resp, err = h.runserviceClient.RunActions(ctx, req.RunID, rsreq) if _, err = h.runserviceClient.RunActions(ctx, req.RunID, rsreq); err != nil {
if err != nil { return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
return nil, ErrFromRemote(resp, err)
} }
case RunActionTypeStop: case RunActionTypeStop:
@ -232,13 +230,12 @@ func (h *ActionHandler) RunAction(ctx context.Context, req *RunActionsRequest) (
ActionType: rsapitypes.RunActionTypeStop, ActionType: rsapitypes.RunActionTypeStop,
} }
resp, err = h.runserviceClient.RunActions(ctx, req.RunID, rsreq) if _, err = h.runserviceClient.RunActions(ctx, req.RunID, rsreq); err != nil {
if err != nil { return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
return nil, ErrFromRemote(resp, err)
} }
default: default:
return nil, util.NewErrBadRequest(errors.Errorf("wrong run action type %q", req.ActionType)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong run action type %q", req.ActionType))
} }
return runResp, nil return runResp, nil
@ -258,27 +255,27 @@ type RunTaskActionsRequest struct {
} }
func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRequest) error { func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRequest) error {
runResp, resp, err := h.runserviceClient.GetRun(ctx, req.RunID, nil) runResp, _, err := h.runserviceClient.GetRun(ctx, req.RunID, nil)
if err != nil { if err != nil {
return ErrFromRemote(resp, err) return util.NewAPIError(util.KindFromRemoteError(err), err)
} }
canDoRunAction, err := h.CanDoRunActions(ctx, runResp.RunConfig.Group) canDoRunAction, err := h.CanDoRunActions(ctx, runResp.RunConfig.Group)
if err != nil { if err != nil {
return errors.Errorf("failed to determine permissions: %w", err) return errors.Errorf("failed to determine permissions: %w", err)
} }
if !canDoRunAction { if !canDoRunAction {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
if curUserID == "" { if curUserID == "" {
return util.NewErrBadRequest(errors.Errorf("no logged in user")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("no logged in user"))
} }
switch req.ActionType { switch req.ActionType {
case RunTaskActionTypeApprove: case RunTaskActionTypeApprove:
rt, ok := runResp.Run.Tasks[req.TaskID] rt, ok := runResp.Run.Tasks[req.TaskID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("run %q doesn't have task %q", req.RunID, req.TaskID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("run %q doesn't have task %q", req.RunID, req.TaskID))
} }
approvers := []string{} approvers := []string{}
@ -295,7 +292,7 @@ func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRe
for _, approver := range approvers { for _, approver := range approvers {
if approver == curUserID { if approver == curUserID {
return util.NewErrBadRequest(errors.Errorf("user %q alredy approved the task", approver)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q alredy approved the task", approver))
} }
} }
approvers = append(approvers, curUserID) approvers = append(approvers, curUserID)
@ -313,13 +310,12 @@ func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRe
ChangeGroupsUpdateToken: runResp.ChangeGroupsUpdateToken, ChangeGroupsUpdateToken: runResp.ChangeGroupsUpdateToken,
} }
resp, err := h.runserviceClient.RunTaskActions(ctx, req.RunID, req.TaskID, rsreq) if _, err := h.runserviceClient.RunTaskActions(ctx, req.RunID, req.TaskID, rsreq); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), err)
return ErrFromRemote(resp, err)
} }
default: default:
return util.NewErrBadRequest(errors.Errorf("wrong run task action type %q", req.ActionType)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong run task action type %q", req.ActionType))
} }
return nil return nil
@ -367,10 +363,10 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
setupErrors := []string{} setupErrors := []string{}
if req.CommitSHA == "" { if req.CommitSHA == "" {
return util.NewErrBadRequest(errors.Errorf("empty commit SHA")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty commit SHA"))
} }
if req.Message == "" { if req.Message == "" {
return util.NewErrBadRequest(errors.Errorf("empty message")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty message"))
} }
var baseGroupType scommon.GroupType var baseGroupType scommon.GroupType
@ -485,7 +481,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
data, filename, err := h.fetchConfigFiles(ctx, req.GitSource, req.RepoPath, req.CommitSHA) data, filename, err := h.fetchConfigFiles(ctx, req.GitSource, req.RepoPath, req.CommitSHA)
if err != nil { if err != nil {
return util.NewErrInternal(errors.Errorf("failed to fetch config file: %w", err)) return util.NewAPIError(util.ErrInternal, errors.Errorf("failed to fetch config file: %w", err))
} }
h.log.Debug("data: %s", data) h.log.Debug("data: %s", data)
@ -529,7 +525,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
if _, _, err := h.runserviceClient.CreateRun(ctx, createRunReq); err != nil { if _, _, err := h.runserviceClient.CreateRun(ctx, createRunReq); err != nil {
h.log.Errorf("failed to create run: %+v", err) h.log.Errorf("failed to create run: %+v", err)
return err return util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return nil return nil
} }
@ -559,7 +555,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
if _, _, err := h.runserviceClient.CreateRun(ctx, createRunReq); err != nil { if _, _, err := h.runserviceClient.CreateRun(ctx, createRunReq); err != nil {
h.log.Errorf("failed to create run: %+v", err) h.log.Errorf("failed to create run: %+v", err)
return err return util.NewAPIError(util.KindFromRemoteError(err), err)
} }
} }

View File

@ -16,7 +16,6 @@ package action
import ( import (
"context" "context"
"net/http"
"agola.io/agola/internal/services/common" "agola.io/agola/internal/services/common"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
@ -36,16 +35,15 @@ type GetSecretsRequest struct {
func (h *ActionHandler) GetSecrets(ctx context.Context, req *GetSecretsRequest) ([]*csapitypes.Secret, error) { func (h *ActionHandler) GetSecrets(ctx context.Context, req *GetSecretsRequest) ([]*csapitypes.Secret, error) {
var cssecrets []*csapitypes.Secret var cssecrets []*csapitypes.Secret
var resp *http.Response
var err error var err error
switch req.ParentType { switch req.ParentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, req.Tree) cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, req.Tree)
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, req.Tree) cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, req.Tree)
} }
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
if req.RemoveOverridden { if req.RemoveOverridden {
@ -78,11 +76,11 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, req *CreateSecretReque
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isVariableOwner { if !isVariableOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid secret name %q", req.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid secret name %q", req.Name))
} }
s := &cstypes.Secret{ s := &cstypes.Secret{
@ -91,18 +89,17 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, req *CreateSecretReque
Data: req.Data, Data: req.Data,
} }
var resp *http.Response
var rs *csapitypes.Secret var rs *csapitypes.Secret
switch req.ParentType { switch req.ParentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
h.log.Infof("creating project group secret") h.log.Infof("creating project group secret")
rs, resp, err = h.configstoreClient.CreateProjectGroupSecret(ctx, req.ParentRef, s) rs, _, err = h.configstoreClient.CreateProjectGroupSecret(ctx, req.ParentRef, s)
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
h.log.Infof("creating project secret") h.log.Infof("creating project secret")
rs, resp, err = h.configstoreClient.CreateProjectSecret(ctx, req.ParentRef, s) rs, _, err = h.configstoreClient.CreateProjectSecret(ctx, req.ParentRef, s)
} }
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create secret: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create secret: %w", err))
} }
h.log.Infof("secret %s created, ID: %s", rs.Name, rs.ID) h.log.Infof("secret %s created, ID: %s", rs.Name, rs.ID)
@ -133,11 +130,11 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
return nil, errors.Errorf("failed to determine ownership: %w", err) return nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isVariableOwner { if !isVariableOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid secret name %q", req.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid secret name %q", req.Name))
} }
s := &cstypes.Secret{ s := &cstypes.Secret{
@ -146,18 +143,17 @@ func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretReque
Data: req.Data, Data: req.Data,
} }
var resp *http.Response
var rs *csapitypes.Secret var rs *csapitypes.Secret
switch req.ParentType { switch req.ParentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
h.log.Infof("updating project group secret") h.log.Infof("updating project group secret")
rs, resp, err = h.configstoreClient.UpdateProjectGroupSecret(ctx, req.ParentRef, req.SecretName, s) rs, _, err = h.configstoreClient.UpdateProjectGroupSecret(ctx, req.ParentRef, req.SecretName, s)
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
h.log.Infof("updating project secret") h.log.Infof("updating project secret")
rs, resp, err = h.configstoreClient.UpdateProjectSecret(ctx, req.ParentRef, req.SecretName, s) rs, _, err = h.configstoreClient.UpdateProjectSecret(ctx, req.ParentRef, req.SecretName, s)
} }
if err != nil { if err != nil {
return nil, errors.Errorf("failed to update secret: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to update secret: %w", err))
} }
h.log.Infof("secret %s updated, ID: %s", rs.Name, rs.ID) h.log.Infof("secret %s updated, ID: %s", rs.Name, rs.ID)
@ -170,20 +166,19 @@ func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType cstypes.Con
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isVariableOwner { if !isVariableOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
var resp *http.Response
switch parentType { switch parentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
h.log.Infof("deleting project group secret") h.log.Infof("deleting project group secret")
resp, err = h.configstoreClient.DeleteProjectGroupSecret(ctx, parentRef, name) _, err = h.configstoreClient.DeleteProjectGroupSecret(ctx, parentRef, name)
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
h.log.Infof("deleting project secret") h.log.Infof("deleting project secret")
resp, err = h.configstoreClient.DeleteProjectSecret(ctx, parentRef, name) _, err = h.configstoreClient.DeleteProjectSecret(ctx, parentRef, name)
} }
if err != nil { if err != nil {
return errors.Errorf("failed to delete secret: %w", ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to delete secret: %w", err))
} }
return nil return nil
} }

View File

@ -51,9 +51,9 @@ func (h *ActionHandler) GetUser(ctx context.Context, userRef string) (*cstypes.U
return nil, errors.Errorf("user not logged in") return nil, errors.Errorf("user not logged in")
} }
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return user, nil return user, nil
} }
@ -63,9 +63,9 @@ func (h *ActionHandler) GetUserOrgs(ctx context.Context, userRef string) ([]*csa
return nil, errors.Errorf("user not logged in") return nil, errors.Errorf("user not logged in")
} }
orgs, resp, err := h.configstoreClient.GetUserOrgs(ctx, userRef) orgs, _, err := h.configstoreClient.GetUserOrgs(ctx, userRef)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return orgs, nil return orgs, nil
} }
@ -81,9 +81,9 @@ func (h *ActionHandler) GetUsers(ctx context.Context, req *GetUsersRequest) ([]*
return nil, errors.Errorf("user not logged in") return nil, errors.Errorf("user not logged in")
} }
users, resp, err := h.configstoreClient.GetUsers(ctx, req.Start, req.Limit, req.Asc) users, _, err := h.configstoreClient.GetUsers(ctx, req.Start, req.Limit, req.Asc)
if err != nil { if err != nil {
return nil, ErrFromRemote(resp, err) return nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
return users, nil return users, nil
} }
@ -98,10 +98,10 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
} }
if req.UserName == "" { if req.UserName == "" {
return nil, util.NewErrBadRequest(errors.Errorf("user name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user name required"))
} }
if !util.ValidateName(req.UserName) { if !util.ValidateName(req.UserName) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid user name %q", req.UserName)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid user name %q", req.UserName))
} }
creq := &csapitypes.CreateUserRequest{ creq := &csapitypes.CreateUserRequest{
@ -109,9 +109,9 @@ func (h *ActionHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
} }
h.log.Infof("creating user") h.log.Infof("creating user")
u, resp, err := h.configstoreClient.CreateUser(ctx, creq) u, _, err := h.configstoreClient.CreateUser(ctx, creq)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create user: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create user: %w", err))
} }
h.log.Infof("user %s created, ID: %s", u.Name, u.ID) h.log.Infof("user %s created, ID: %s", u.Name, u.ID)
@ -128,26 +128,26 @@ func (h *ActionHandler) CreateUserToken(ctx context.Context, req *CreateUserToke
userID := common.CurrentUserID(ctx) userID := common.CurrentUserID(ctx)
userRef := req.UserRef userRef := req.UserRef
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return "", errors.Errorf("failed to get user: %w", ErrFromRemote(resp, err)) return "", util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user: %w", err))
} }
// only admin or the same logged user can create a token // only admin or the same logged user can create a token
if !isAdmin && user.ID != userID { if !isAdmin && user.ID != userID {
return "", util.NewErrBadRequest(errors.Errorf("logged in user cannot create token for another user")) return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("logged in user cannot create token for another user"))
} }
if _, ok := user.Tokens[req.TokenName]; ok { if _, ok := user.Tokens[req.TokenName]; ok {
return "", util.NewErrBadRequest(errors.Errorf("user %q already have a token with name %q", userRef, req.TokenName)) return "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q already have a token with name %q", userRef, req.TokenName))
} }
h.log.Infof("creating user token") h.log.Infof("creating user token")
creq := &csapitypes.CreateUserTokenRequest{ creq := &csapitypes.CreateUserTokenRequest{
TokenName: req.TokenName, TokenName: req.TokenName,
} }
res, resp, err := h.configstoreClient.CreateUserToken(ctx, userRef, creq) res, _, err := h.configstoreClient.CreateUserToken(ctx, userRef, creq)
if err != nil { if err != nil {
return "", errors.Errorf("failed to create user token: %w", ErrFromRemote(resp, err)) return "", util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create user token: %w", err))
} }
h.log.Infof("token %q for user %q created", req.TokenName, userRef) h.log.Infof("token %q for user %q created", req.TokenName, userRef)
@ -166,13 +166,13 @@ type CreateUserLARequest struct {
func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLARequest) (*cstypes.LinkedAccount, error) { func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLARequest) (*cstypes.LinkedAccount, error) {
userRef := req.UserRef userRef := req.UserRef
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get user %q: %w", userRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", userRef, err))
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, err))
} }
var la *cstypes.LinkedAccount var la *cstypes.LinkedAccount
for _, v := range user.LinkedAccounts { for _, v := range user.LinkedAccounts {
@ -182,7 +182,7 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
} }
} }
if la != nil { if la != nil {
return nil, util.NewErrBadRequest(errors.Errorf("user %q already have a linked account for remote source %q", userRef, rs.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q already have a linked account for remote source %q", userRef, rs.Name))
} }
accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken) accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken)
@ -213,9 +213,9 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
} }
h.log.Infof("creating linked account") h.log.Infof("creating linked account")
la, resp, err = h.configstoreClient.CreateUserLA(ctx, userRef, creq) la, _, err = h.configstoreClient.CreateUserLA(ctx, userRef, creq)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create linked account: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create linked account: %w", err))
} }
h.log.Infof("linked account %q for user %q created", la.ID, userRef) h.log.Infof("linked account %q for user %q created", la.ID, userRef)
@ -223,9 +223,9 @@ func (h *ActionHandler) CreateUserLA(ctx context.Context, req *CreateUserLAReque
} }
func (h *ActionHandler) UpdateUserLA(ctx context.Context, userRef string, la *cstypes.LinkedAccount) error { func (h *ActionHandler) UpdateUserLA(ctx context.Context, userRef string, la *cstypes.LinkedAccount) error {
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get user %q: %w", userRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", userRef, err))
} }
laFound := false laFound := false
for _, ula := range user.LinkedAccounts { for _, ula := range user.LinkedAccounts {
@ -235,7 +235,7 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, userRef string, la *cs
} }
} }
if !laFound { if !laFound {
return util.NewErrBadRequest(errors.Errorf("user %q doesn't have a linked account with id %q", userRef, la.ID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q doesn't have a linked account with id %q", userRef, la.ID))
} }
creq := &csapitypes.UpdateUserLARequest{ creq := &csapitypes.UpdateUserLARequest{
@ -248,9 +248,9 @@ func (h *ActionHandler) UpdateUserLA(ctx context.Context, userRef string, la *cs
} }
h.log.Infof("updating user %q linked account", userRef) h.log.Infof("updating user %q linked account", userRef)
la, resp, err = h.configstoreClient.UpdateUserLA(ctx, userRef, la.ID, creq) la, _, err = h.configstoreClient.UpdateUserLA(ctx, userRef, la.ID, creq)
if err != nil { if err != nil {
return errors.Errorf("failed to update user: %w", ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to update user: %w", err))
} }
h.log.Infof("linked account %q for user %q updated", la.ID, userRef) h.log.Infof("linked account %q for user %q updated", la.ID, userRef)
@ -307,18 +307,18 @@ type RegisterUserRequest struct {
func (h *ActionHandler) RegisterUser(ctx context.Context, req *RegisterUserRequest) (*cstypes.User, error) { func (h *ActionHandler) RegisterUser(ctx context.Context, req *RegisterUserRequest) (*cstypes.User, error) {
if req.UserName == "" { if req.UserName == "" {
return nil, util.NewErrBadRequest(errors.Errorf("user name required")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user name required"))
} }
if !util.ValidateName(req.UserName) { if !util.ValidateName(req.UserName) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid user name %q", req.UserName)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid user name %q", req.UserName))
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, err))
} }
if !*rs.RegistrationEnabled { if !*rs.RegistrationEnabled {
return nil, util.NewErrBadRequest(errors.Errorf("remote source user registration is disabled")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source user registration is disabled"))
} }
accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken) accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken)
@ -352,9 +352,9 @@ func (h *ActionHandler) RegisterUser(ctx context.Context, req *RegisterUserReque
} }
h.log.Infof("creating user account") h.log.Infof("creating user account")
u, resp, err := h.configstoreClient.CreateUser(ctx, creq) u, _, err := h.configstoreClient.CreateUser(ctx, creq)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to create linked account: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create linked account: %w", err))
} }
h.log.Infof("user %q created", req.UserName) h.log.Infof("user %q created", req.UserName)
@ -375,12 +375,12 @@ type LoginUserResponse struct {
} }
func (h *ActionHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*LoginUserResponse, error) { func (h *ActionHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*LoginUserResponse, error) {
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, err))
} }
if !*rs.LoginEnabled { if !*rs.LoginEnabled {
return nil, util.NewErrBadRequest(errors.Errorf("remote source user login is disabled")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("remote source user login is disabled"))
} }
accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken) accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken)
@ -400,9 +400,9 @@ func (h *ActionHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*
return nil, errors.Errorf("empty remote user id for remote source %q", rs.ID) return nil, errors.Errorf("empty remote user id for remote source %q", rs.ID)
} }
user, resp, err := h.configstoreClient.GetUserByLinkedAccountRemoteUserAndSource(ctx, remoteUserInfo.ID, rs.ID) user, _, err := h.configstoreClient.GetUserByLinkedAccountRemoteUserAndSource(ctx, remoteUserInfo.ID, rs.ID)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", remoteUserInfo.ID, rs.ID, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user for remote user id %q and remote source %q: %w", remoteUserInfo.ID, rs.ID, err))
} }
var la *cstypes.LinkedAccount var la *cstypes.LinkedAccount
@ -435,9 +435,9 @@ func (h *ActionHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*
} }
h.log.Infof("updating user %q linked account", user.Name) h.log.Infof("updating user %q linked account", user.Name)
la, resp, err = h.configstoreClient.UpdateUserLA(ctx, user.Name, la.ID, creq) la, _, err = h.configstoreClient.UpdateUserLA(ctx, user.Name, la.ID, creq)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to update user: %w", ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to update user: %w", err))
} }
h.log.Infof("linked account %q for user %q updated", la.ID, user.Name) h.log.Infof("linked account %q for user %q updated", la.ID, user.Name)
} }
@ -467,9 +467,9 @@ type AuthorizeResponse struct {
} }
func (h *ActionHandler) Authorize(ctx context.Context, req *AuthorizeRequest) (*AuthorizeResponse, error) { func (h *ActionHandler) Authorize(ctx context.Context, req *AuthorizeRequest) (*AuthorizeResponse, error) {
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, req.RemoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, err))
} }
accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken) accessToken, err := scommon.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken)
@ -501,18 +501,18 @@ type RemoteSourceAuthResponse struct {
} }
func (h *ActionHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSourceName, loginName, loginPassword string, requestType RemoteSourceRequestType, req interface{}) (*RemoteSourceAuthResponse, error) { func (h *ActionHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSourceName, loginName, loginPassword string, requestType RemoteSourceRequestType, req interface{}) (*RemoteSourceAuthResponse, error) {
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, remoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, remoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", remoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", remoteSourceName, err))
} }
switch requestType { switch requestType {
case RemoteSourceRequestTypeCreateUserLA: case RemoteSourceRequestTypeCreateUserLA:
req := req.(*CreateUserLARequest) req := req.(*CreateUserLARequest)
user, resp, err := h.configstoreClient.GetUser(ctx, req.UserRef) user, _, err := h.configstoreClient.GetUser(ctx, req.UserRef)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get user %q: %w", req.UserRef, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", req.UserRef, err))
} }
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
@ -520,7 +520,7 @@ func (h *ActionHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSource
// user must be already logged in the create a linked account and can create a // user must be already logged in the create a linked account and can create a
// linked account only on itself. // linked account only on itself.
if user.ID != curUserID { if user.ID != curUserID {
return nil, util.NewErrBadRequest(errors.Errorf("logged in user cannot create linked account for another user")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("logged in user cannot create linked account for another user"))
} }
var la *cstypes.LinkedAccount var la *cstypes.LinkedAccount
@ -531,7 +531,7 @@ func (h *ActionHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSource
} }
} }
if la != nil { if la != nil {
return nil, util.NewErrBadRequest(errors.Errorf("user %q already have a linked account for remote source %q", req.UserRef, rs.Name)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user %q already have a linked account for remote source %q", req.UserRef, rs.Name))
} }
case RemoteSourceRequestTypeLoginUser: case RemoteSourceRequestTypeLoginUser:
@ -572,7 +572,7 @@ func (h *ActionHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSource
accessToken, err := passwordSource.LoginPassword(loginName, loginPassword, tokenName) accessToken, err := passwordSource.LoginPassword(loginName, loginPassword, tokenName)
if err != nil { if err != nil {
if errors.Is(err, gitsource.ErrUnauthorized) { if errors.Is(err, gitsource.ErrUnauthorized) {
return nil, util.NewErrUnauthorized(errors.Errorf("failed to login to remotesource %q: %w", remoteSourceName, err)) return nil, util.NewAPIError(util.ErrUnauthorized, errors.Errorf("failed to login to remotesource %q: %w", remoteSourceName, err))
} }
return nil, errors.Errorf("failed to login to remote source %q with login name %q: %w", rs.Name, loginName, err) return nil, errors.Errorf("failed to login to remote source %q with login name %q: %w", rs.Name, loginName, err)
} }
@ -738,9 +738,9 @@ func (h *ActionHandler) HandleOauth2Callback(ctx context.Context, code, state st
requestType := RemoteSourceRequestType(claims["request_type"].(string)) requestType := RemoteSourceRequestType(claims["request_type"].(string))
requestString := claims["request"].(string) requestString := claims["request"].(string)
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, remoteSourceName) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, remoteSourceName)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", remoteSourceName, ErrFromRemote(resp, err)) return nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get remote source %q: %w", remoteSourceName, err))
} }
oauth2Source, err := scommon.GetOauth2Source(rs, "") oauth2Source, err := scommon.GetOauth2Source(rs, "")
@ -761,9 +761,8 @@ func (h *ActionHandler) DeleteUser(ctx context.Context, userRef string) error {
return errors.Errorf("user not logged in") return errors.Errorf("user not logged in")
} }
resp, err := h.configstoreClient.DeleteUser(ctx, userRef) if _, err := h.configstoreClient.DeleteUser(ctx, userRef); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to delete user: %w", err))
return errors.Errorf("failed to delete user: %w", ErrFromRemote(resp, err))
} }
return nil return nil
} }
@ -776,19 +775,18 @@ func (h *ActionHandler) DeleteUserLA(ctx context.Context, userRef, laID string)
isAdmin := common.IsUserAdmin(ctx) isAdmin := common.IsUserAdmin(ctx)
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get user %q: %w", userRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", userRef, err))
} }
// only admin or the same logged user can create a token // only admin or the same logged user can create a token
if !isAdmin && user.ID != curUserID { if !isAdmin && user.ID != curUserID {
return util.NewErrBadRequest(errors.Errorf("logged in user cannot create token for another user")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("logged in user cannot create token for another user"))
} }
resp, err = h.configstoreClient.DeleteUserLA(ctx, userRef, laID) if _, err = h.configstoreClient.DeleteUserLA(ctx, userRef, laID); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to delete user linked account: %w", err))
return errors.Errorf("failed to delete user linked account: %w", ErrFromRemote(resp, err))
} }
return nil return nil
} }
@ -801,19 +799,18 @@ func (h *ActionHandler) DeleteUserToken(ctx context.Context, userRef, tokenName
isAdmin := common.IsUserAdmin(ctx) isAdmin := common.IsUserAdmin(ctx)
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
user, resp, err := h.configstoreClient.GetUser(ctx, userRef) user, _, err := h.configstoreClient.GetUser(ctx, userRef)
if err != nil { if err != nil {
return errors.Errorf("failed to get user %q: %w", userRef, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", userRef, err))
} }
// only admin or the same logged user can create a token // only admin or the same logged user can create a token
if !isAdmin && user.ID != curUserID { if !isAdmin && user.ID != curUserID {
return util.NewErrBadRequest(errors.Errorf("logged in user cannot delete token for another user")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("logged in user cannot delete token for another user"))
} }
resp, err = h.configstoreClient.DeleteUserToken(ctx, userRef, tokenName) if _, err = h.configstoreClient.DeleteUserToken(ctx, userRef, tokenName); err != nil {
if err != nil { return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to delete user token: %w", err))
return errors.Errorf("failed to delete user token: %w", ErrFromRemote(resp, err))
} }
return nil return nil
} }
@ -843,21 +840,21 @@ func (h *ActionHandler) UserCreateRun(ctx context.Context, req *UserCreateRunReq
curUserID := common.CurrentUserID(ctx) curUserID := common.CurrentUserID(ctx)
user, resp, err := h.configstoreClient.GetUser(ctx, curUserID) user, _, err := h.configstoreClient.GetUser(ctx, curUserID)
if err != nil { if err != nil {
return errors.Errorf("failed to get user %q: %w", curUserID, ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get user %q: %w", curUserID, err))
} }
// Verify that the repo is owned by the user // Verify that the repo is owned by the user
repoParts := strings.Split(req.RepoPath, "/") repoParts := strings.Split(req.RepoPath, "/")
if req.RepoUUID == "" { if req.RepoUUID == "" {
return util.NewErrBadRequest(errors.Errorf("empty repo uuid")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty repo uuid"))
} }
if len(repoParts) != 2 { if len(repoParts) != 2 {
return util.NewErrBadRequest(errors.Errorf("wrong repo path: %q", req.RepoPath)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong repo path: %q", req.RepoPath))
} }
if repoParts[0] != user.ID { if repoParts[0] != user.ID {
return util.NewErrUnauthorized(errors.Errorf("repo %q not owned", req.RepoPath)) return util.NewAPIError(util.ErrUnauthorized, errors.Errorf("repo %q not owned", req.RepoPath))
} }
branch := req.Branch branch := req.Branch
@ -875,10 +872,10 @@ func (h *ActionHandler) UserCreateRun(ctx context.Context, req *UserCreateRunReq
set++ set++
} }
if set == 0 { if set == 0 {
return util.NewErrBadRequest(errors.Errorf("one of branch, tag or ref is required")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("one of branch, tag or ref is required"))
} }
if set > 1 { if set > 1 {
return util.NewErrBadRequest(errors.Errorf("only one of branch, tag or ref can be provided")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("only one of branch, tag or ref can be provided"))
} }
gitSource := agolagit.New(h.apiExposedURL+"/repos", prRefRegexes) gitSource := agolagit.New(h.apiExposedURL+"/repos", prRefRegexes)
@ -895,7 +892,7 @@ func (h *ActionHandler) UserCreateRun(ctx context.Context, req *UserCreateRunReq
gitRefType, name, err := gitSource.RefType(ref) gitRefType, name, err := gitSource.RefType(ref)
if err != nil { if err != nil {
return util.NewErrBadRequest(errors.Errorf("failed to get refType for ref %q: %w", ref, err)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("failed to get refType for ref %q: %w", ref, err))
} }
var pullRequestID string var pullRequestID string

View File

@ -16,7 +16,6 @@ package action
import ( import (
"context" "context"
"net/http"
"agola.io/agola/internal/services/common" "agola.io/agola/internal/services/common"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
@ -40,25 +39,23 @@ func (h *ActionHandler) GetVariables(ctx context.Context, req *GetVariablesReque
switch req.ParentType { switch req.ParentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
var err error var err error
var resp *http.Response csvars, _, err = h.configstoreClient.GetProjectGroupVariables(ctx, req.ParentRef, req.Tree)
csvars, resp, err = h.configstoreClient.GetProjectGroupVariables(ctx, req.ParentRef, req.Tree)
if err != nil { if err != nil {
return nil, nil, ErrFromRemote(resp, err) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, true) cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, true)
if err != nil { if err != nil {
return nil, nil, ErrFromRemote(resp, err) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
var err error var err error
var resp *http.Response csvars, _, err = h.configstoreClient.GetProjectVariables(ctx, req.ParentRef, req.Tree)
csvars, resp, err = h.configstoreClient.GetProjectVariables(ctx, req.ParentRef, req.Tree)
if err != nil { if err != nil {
return nil, nil, ErrFromRemote(resp, err) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, true) cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, true)
if err != nil { if err != nil {
return nil, nil, ErrFromRemote(resp, err) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), err)
} }
} }
@ -85,15 +82,15 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, req *CreateVariableR
return nil, nil, errors.Errorf("failed to determine ownership: %w", err) return nil, nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isVariableOwner { if !isVariableOwner {
return nil, nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, nil, util.NewErrBadRequest(errors.Errorf("invalid variable name %q", req.Name)) return nil, nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid variable name %q", req.Name))
} }
if len(req.Values) == 0 { if len(req.Values) == 0 {
return nil, nil, util.NewErrBadRequest(errors.Errorf("empty variable values")) return nil, nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty variable values"))
} }
v := &cstypes.Variable{ v := &cstypes.Variable{
@ -111,29 +108,27 @@ func (h *ActionHandler) CreateVariable(ctx context.Context, req *CreateVariableR
switch req.ParentType { switch req.ParentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
var err error var err error
var resp *http.Response cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, true)
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, true)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to get project group %q secrets: %w", req.ParentRef, ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project group %q secrets: %w", req.ParentRef, err))
} }
h.log.Infof("creating project group variable") h.log.Infof("creating project group variable")
rv, resp, err = h.configstoreClient.CreateProjectGroupVariable(ctx, req.ParentRef, v) rv, _, err = h.configstoreClient.CreateProjectGroupVariable(ctx, req.ParentRef, v)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to create variable: %w", ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create variable: %w", err))
} }
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
var err error var err error
var resp *http.Response cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, true)
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, true)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to get project %q secrets: %w", req.ParentRef, ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q secrets: %w", req.ParentRef, err))
} }
h.log.Infof("creating project variable") h.log.Infof("creating project variable")
rv, resp, err = h.configstoreClient.CreateProjectVariable(ctx, req.ParentRef, v) rv, _, err = h.configstoreClient.CreateProjectVariable(ctx, req.ParentRef, v)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to create variable: %w", ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create variable: %w", err))
} }
} }
h.log.Infof("variable %s created, ID: %s", rv.Name, rv.ID) h.log.Infof("variable %s created, ID: %s", rv.Name, rv.ID)
@ -158,15 +153,15 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
return nil, nil, errors.Errorf("failed to determine ownership: %w", err) return nil, nil, errors.Errorf("failed to determine ownership: %w", err)
} }
if !isVariableOwner { if !isVariableOwner {
return nil, nil, util.NewErrForbidden(errors.Errorf("user not authorized")) return nil, nil, util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
if !util.ValidateName(req.Name) { if !util.ValidateName(req.Name) {
return nil, nil, util.NewErrBadRequest(errors.Errorf("invalid variable name %q", req.Name)) return nil, nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("invalid variable name %q", req.Name))
} }
if len(req.Values) == 0 { if len(req.Values) == 0 {
return nil, nil, util.NewErrBadRequest(errors.Errorf("empty variable values")) return nil, nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty variable values"))
} }
v := &cstypes.Variable{ v := &cstypes.Variable{
@ -184,29 +179,27 @@ func (h *ActionHandler) UpdateVariable(ctx context.Context, req *UpdateVariableR
switch req.ParentType { switch req.ParentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
var err error var err error
var resp *http.Response cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, true)
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, req.ParentRef, true)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to get project group %q secrets: %w", req.ParentRef, ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project group %q secrets: %w", req.ParentRef, err))
} }
h.log.Infof("creating project group variable") h.log.Infof("creating project group variable")
rv, resp, err = h.configstoreClient.UpdateProjectGroupVariable(ctx, req.ParentRef, req.VariableName, v) rv, _, err = h.configstoreClient.UpdateProjectGroupVariable(ctx, req.ParentRef, req.VariableName, v)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to create variable: %w", ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create variable: %w", err))
} }
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
var err error var err error
var resp *http.Response cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, true)
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, req.ParentRef, true)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to get project %q secrets: %w", req.ParentRef, ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to get project %q secrets: %w", req.ParentRef, err))
} }
h.log.Infof("creating project variable") h.log.Infof("creating project variable")
rv, resp, err = h.configstoreClient.UpdateProjectVariable(ctx, req.ParentRef, req.VariableName, v) rv, _, err = h.configstoreClient.UpdateProjectVariable(ctx, req.ParentRef, req.VariableName, v)
if err != nil { if err != nil {
return nil, nil, errors.Errorf("failed to create variable: %w", ErrFromRemote(resp, err)) return nil, nil, util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to create variable: %w", err))
} }
} }
h.log.Infof("variable %s created, ID: %s", rv.Name, rv.ID) h.log.Infof("variable %s created, ID: %s", rv.Name, rv.ID)
@ -220,20 +213,19 @@ func (h *ActionHandler) DeleteVariable(ctx context.Context, parentType cstypes.C
return errors.Errorf("failed to determine ownership: %w", err) return errors.Errorf("failed to determine ownership: %w", err)
} }
if !isVariableOwner { if !isVariableOwner {
return util.NewErrForbidden(errors.Errorf("user not authorized")) return util.NewAPIError(util.ErrForbidden, errors.Errorf("user not authorized"))
} }
var resp *http.Response
switch parentType { switch parentType {
case cstypes.ConfigTypeProjectGroup: case cstypes.ConfigTypeProjectGroup:
h.log.Infof("deleting project group variable") h.log.Infof("deleting project group variable")
resp, err = h.configstoreClient.DeleteProjectGroupVariable(ctx, parentRef, name) _, err = h.configstoreClient.DeleteProjectGroupVariable(ctx, parentRef, name)
case cstypes.ConfigTypeProject: case cstypes.ConfigTypeProject:
h.log.Infof("deleting project variable") h.log.Infof("deleting project variable")
resp, err = h.configstoreClient.DeleteProjectVariable(ctx, parentRef, name) _, err = h.configstoreClient.DeleteProjectVariable(ctx, parentRef, name)
} }
if err != nil { if err != nil {
return errors.Errorf("failed to delete variable: %w", ErrFromRemote(resp, err)) return util.NewAPIError(util.KindFromRemoteError(err), errors.Errorf("failed to delete variable: %w", err))
} }
return nil return nil
} }

View File

@ -15,7 +15,6 @@
package api package api
import ( import (
"encoding/json"
"net/http" "net/http"
"net/url" "net/url"
@ -26,124 +25,11 @@ import (
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
) )
type ErrorResponse struct {
Message string `json:"message"`
}
func ErrorResponseFromError(err error) *ErrorResponse {
var aerr error
// use inner errors if of these types
switch {
case util.IsBadRequest(err):
var cerr *util.ErrBadRequest
errors.As(err, &cerr)
aerr = cerr
case util.IsNotExist(err):
var cerr *util.ErrNotExist
errors.As(err, &cerr)
aerr = cerr
case util.IsForbidden(err):
var cerr *util.ErrForbidden
errors.As(err, &cerr)
aerr = cerr
case util.IsUnauthorized(err):
var cerr *util.ErrUnauthorized
errors.As(err, &cerr)
aerr = cerr
case util.IsInternal(err):
var cerr *util.ErrInternal
errors.As(err, &cerr)
aerr = cerr
}
if aerr != nil {
return &ErrorResponse{Message: aerr.Error()}
}
// on generic error return an generic message to not leak the real error
return &ErrorResponse{Message: "internal server error"}
}
func httpError(w http.ResponseWriter, err error) bool {
if err == nil {
return false
}
response := ErrorResponseFromError(err)
resj, merr := json.Marshal(response)
if merr != nil {
w.WriteHeader(http.StatusInternalServerError)
return true
}
switch {
case util.IsBadRequest(err):
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write(resj)
case util.IsNotExist(err):
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write(resj)
case util.IsForbidden(err):
w.WriteHeader(http.StatusForbidden)
_, _ = w.Write(resj)
case util.IsUnauthorized(err):
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write(resj)
case util.IsInternal(err):
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write(resj)
default:
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write(resj)
}
return true
}
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
w.Header().Set("Content-Type", "application/json")
if res != nil {
resj, err := json.Marshal(res)
if err != nil {
httpError(w, err)
return err
}
w.WriteHeader(code)
_, err = w.Write(resj)
return err
}
w.WriteHeader(code)
return nil
}
func httpErrorFromRemote(w http.ResponseWriter, resp *http.Response, err error) bool {
if err != nil {
// on generic error return an generic message to not leak the real error
response := &ErrorResponse{Message: "internal server error"}
if resp != nil {
response = &ErrorResponse{Message: err.Error()}
}
resj, merr := json.Marshal(response)
if merr != nil {
w.WriteHeader(http.StatusInternalServerError)
return true
}
if resp != nil {
w.WriteHeader(resp.StatusCode)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
_, _ = w.Write(resj)
return true
}
return false
}
func GetConfigTypeRef(r *http.Request) (cstypes.ConfigType, string, error) { func GetConfigTypeRef(r *http.Request) (cstypes.ConfigType, string, error) {
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
return "", "", util.NewErrBadRequest(errors.Errorf("wrong projectref %q: %w", vars["projectref"], err)) return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong projectref %q: %w", vars["projectref"], err))
} }
if projectRef != "" { if projectRef != "" {
return cstypes.ConfigTypeProject, projectRef, nil return cstypes.ConfigTypeProject, projectRef, nil
@ -151,11 +37,11 @@ func GetConfigTypeRef(r *http.Request) (cstypes.ConfigType, string, error) {
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
return "", "", util.NewErrBadRequest(errors.Errorf("wrong projectgroupref %q: %w", vars["projectgroupref"], err)) return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("wrong projectgroupref %q: %w", vars["projectgroupref"], err))
} }
if projectGroupRef != "" { if projectGroupRef != "" {
return cstypes.ConfigTypeProjectGroup, projectGroupRef, nil return cstypes.ConfigTypeProjectGroup, projectGroupRef, nil
} }
return "", "", util.NewErrBadRequest(errors.Errorf("cannot get project or projectgroup ref")) return "", "", util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot get project or projectgroup ref"))
} }

View File

@ -20,6 +20,7 @@ import (
"agola.io/agola/internal/services/gateway/action" "agola.io/agola/internal/services/gateway/action"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -40,13 +41,13 @@ func (h *BadgeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
branch := query.Get("branch") branch := query.Get("branch")
badge, err := h.ah.GetBadge(ctx, projectRef, branch) badge, err := h.ah.GetBadge(ctx, projectRef, branch)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }

View File

@ -42,7 +42,7 @@ func (h *OAuth2CallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
cresp, err := h.ah.HandleOauth2Callback(ctx, code, state) cresp, err := h.ah.HandleOauth2Callback(ctx, code, state)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -86,7 +86,7 @@ func (h *OAuth2CallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
RequestType: string(cresp.RequestType), RequestType: string(cresp.RequestType),
Response: response, Response: response,
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -47,7 +47,7 @@ func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req gwapitypes.CreateOrgRequest var req gwapitypes.CreateOrgRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -58,13 +58,13 @@ func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
org, err := h.ah.CreateOrg(ctx, creq) org, err := h.ah.CreateOrg(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createOrgResponse(org) res := createOrgResponse(org)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -84,12 +84,12 @@ func (h *DeleteOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
orgRef := vars["orgref"] orgRef := vars["orgref"]
err := h.ah.DeleteOrg(ctx, orgRef) err := h.ah.DeleteOrg(ctx, orgRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -109,13 +109,13 @@ func (h *OrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
orgRef := vars["orgref"] orgRef := vars["orgref"]
org, err := h.ah.GetOrg(ctx, orgRef) org, err := h.ah.GetOrg(ctx, orgRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createOrgResponse(org) res := createOrgResponse(org)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -148,12 +148,12 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxRunsLimit { if limit > MaxRunsLimit {
@ -172,7 +172,7 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Asc: asc, Asc: asc,
} }
csorgs, err := h.ah.GetOrgs(ctx, areq) csorgs, err := h.ah.GetOrgs(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -181,7 +181,7 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for i, p := range csorgs { for i, p := range csorgs {
orgs[i] = createOrgResponse(p) orgs[i] = createOrgResponse(p)
} }
if err := httpResponse(w, http.StatusOK, orgs); err != nil { if err := util.HTTPResponse(w, http.StatusOK, orgs); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -209,7 +209,7 @@ func (h *OrgMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
orgRef := vars["orgref"] orgRef := vars["orgref"]
ares, err := h.ah.GetOrgMembers(ctx, orgRef) ares, err := h.ah.GetOrgMembers(ctx, orgRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -221,7 +221,7 @@ func (h *OrgMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for i, m := range ares.Members { for i, m := range ares.Members {
res.Members[i] = createOrgMemberResponse(m.User, m.Role) res.Members[i] = createOrgMemberResponse(m.User, m.Role)
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -255,18 +255,18 @@ func (h *AddOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req gwapitypes.AddOrgMemberRequest var req gwapitypes.AddOrgMemberRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
ares, err := h.ah.AddOrgMember(ctx, orgRef, userRef, cstypes.MemberRole(req.Role)) ares, err := h.ah.AddOrgMember(ctx, orgRef, userRef, cstypes.MemberRole(req.Role))
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createAddOrgMemberResponse(ares.Org, ares.User, ares.OrganizationMember.MemberRole) res := createAddOrgMemberResponse(ares.Org, ares.User, ares.OrganizationMember.MemberRole)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -288,12 +288,12 @@ func (h *RemoveOrgMemberHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
userRef := vars["userref"] userRef := vars["userref"]
err := h.ah.RemoveOrgMember(ctx, orgRef, userRef) err := h.ah.RemoveOrgMember(ctx, orgRef, userRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -44,7 +44,7 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req gwapitypes.CreateProjectRequest var req gwapitypes.CreateProjectRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -59,13 +59,13 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }
project, err := h.ah.CreateProject(ctx, areq) project, err := h.ah.CreateProject(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectResponse(project) res := createProjectResponse(project)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -84,14 +84,14 @@ func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
var req gwapitypes.UpdateProjectRequest var req gwapitypes.UpdateProjectRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -108,13 +108,13 @@ func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
PassVarsToForkedPR: req.PassVarsToForkedPR, PassVarsToForkedPR: req.PassVarsToForkedPR,
} }
project, err := h.ah.UpdateProject(ctx, projectRef, areq) project, err := h.ah.UpdateProject(ctx, projectRef, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectResponse(project) res := createProjectResponse(project)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -133,15 +133,15 @@ func (h *ProjectReconfigHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
if err := h.ah.ReconfigProject(ctx, projectRef); err != nil { if err := h.ah.ReconfigProject(ctx, projectRef); err != nil {
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -160,18 +160,18 @@ func (h *ProjectUpdateRepoLinkedAccountHandler) ServeHTTP(w http.ResponseWriter,
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
project, err := h.ah.ProjectUpdateRepoLinkedAccount(ctx, projectRef) project, err := h.ah.ProjectUpdateRepoLinkedAccount(ctx, projectRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectResponse(project) res := createProjectResponse(project)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -190,17 +190,17 @@ func (h *DeleteProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
err = h.ah.DeleteProject(ctx, projectRef) err = h.ah.DeleteProject(ctx, projectRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -219,18 +219,18 @@ func (h *ProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
project, err := h.ah.GetProject(ctx, projectRef) project, err := h.ah.GetProject(ctx, projectRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectResponse(project) res := createProjectResponse(project)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -263,24 +263,24 @@ func (h *ProjectCreateRunHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque
vars := mux.Vars(r) vars := mux.Vars(r)
projectRef, err := url.PathUnescape(vars["projectref"]) projectRef, err := url.PathUnescape(vars["projectref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
var req gwapitypes.ProjectCreateRunRequest var req gwapitypes.ProjectCreateRunRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
err = h.ah.ProjectCreateRun(ctx, projectRef, req.Branch, req.Tag, req.Ref, req.CommitSHA) err = h.ah.ProjectCreateRun(ctx, projectRef, req.Branch, req.Tag, req.Ref, req.CommitSHA)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, nil); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -46,13 +46,13 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
var req gwapitypes.CreateProjectGroupRequest var req gwapitypes.CreateProjectGroupRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
userID := common.CurrentUserID(ctx) userID := common.CurrentUserID(ctx)
if userID == "" { if userID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user not authenticated")))
return return
} }
@ -64,13 +64,13 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
} }
projectGroup, err := h.ah.CreateProjectGroup(ctx, creq) projectGroup, err := h.ah.CreateProjectGroup(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectGroupResponse(projectGroup) res := createProjectGroupResponse(projectGroup)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -89,14 +89,14 @@ func (h *UpdateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
var req gwapitypes.UpdateProjectGroupRequest var req gwapitypes.UpdateProjectGroupRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -112,13 +112,13 @@ func (h *UpdateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
Visibility: visibility, Visibility: visibility,
} }
projectGroup, err := h.ah.UpdateProjectGroup(ctx, projectGroupRef, areq) projectGroup, err := h.ah.UpdateProjectGroup(ctx, projectGroupRef, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectGroupResponse(projectGroup) res := createProjectGroupResponse(projectGroup)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -137,17 +137,17 @@ func (h *DeleteProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
err = h.ah.DeleteProjectGroup(ctx, projectGroupRef) err = h.ah.DeleteProjectGroup(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -166,18 +166,18 @@ func (h *ProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
projectGroup, err := h.ah.GetProjectGroup(ctx, projectGroupRef) projectGroup, err := h.ah.GetProjectGroup(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createProjectGroupResponse(projectGroup) res := createProjectGroupResponse(projectGroup)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -196,12 +196,12 @@ func (h *ProjectGroupProjectsHandler) ServeHTTP(w http.ResponseWriter, r *http.R
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
csprojects, err := h.ah.GetProjectGroupProjects(ctx, projectGroupRef) csprojects, err := h.ah.GetProjectGroupProjects(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -211,7 +211,7 @@ func (h *ProjectGroupProjectsHandler) ServeHTTP(w http.ResponseWriter, r *http.R
projects[i] = createProjectResponse(p) projects[i] = createProjectResponse(p)
} }
if err := httpResponse(w, http.StatusOK, projects); err != nil { if err := util.HTTPResponse(w, http.StatusOK, projects); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -230,12 +230,12 @@ func (h *ProjectGroupSubgroupsHandler) ServeHTTP(w http.ResponseWriter, r *http.
vars := mux.Vars(r) vars := mux.Vars(r)
projectGroupRef, err := url.PathUnescape(vars["projectgroupref"]) projectGroupRef, err := url.PathUnescape(vars["projectgroupref"])
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
cssubgroups, err := h.ah.GetProjectGroupSubgroups(ctx, projectGroupRef) cssubgroups, err := h.ah.GetProjectGroupSubgroups(ctx, projectGroupRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -245,7 +245,7 @@ func (h *ProjectGroupSubgroupsHandler) ServeHTTP(w http.ResponseWriter, r *http.
subgroups[i] = createProjectGroupResponse(g) subgroups[i] = createProjectGroupResponse(g)
} }
if err := httpResponse(w, http.StatusOK, subgroups); err != nil { if err := util.HTTPResponse(w, http.StatusOK, subgroups); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -56,18 +56,18 @@ func (h *UserRemoteReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
userID := common.CurrentUserID(ctx) userID := common.CurrentUserID(ctx)
if userID == "" { if userID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user not authenticated")))
return return
} }
user, resp, err := h.configstoreClient.GetUser(ctx, userID) user, _, err := h.configstoreClient.GetUser(ctx, userID)
if httpErrorFromRemote(w, resp, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, remoteSourceRef) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, remoteSourceRef)
if httpErrorFromRemote(w, resp, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -80,23 +80,23 @@ func (h *UserRemoteReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
} }
} }
if la == nil { if la == nil {
err := util.NewErrBadRequest(errors.Errorf("user doesn't have a linked account for remote source %q", rs.Name)) err := util.NewAPIError(util.ErrBadRequest, errors.Errorf("user doesn't have a linked account for remote source %q", rs.Name))
httpError(w, err) util.HTTPError(w, err)
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
gitsource, err := h.ah.GetGitSource(ctx, rs, user.Name, la) gitsource, err := h.ah.GetGitSource(ctx, rs, user.Name, la)
if err != nil { if err != nil {
httpError(w, err) util.HTTPError(w, err)
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
remoteRepos, err := gitsource.ListUserRepos() remoteRepos, err := gitsource.ListUserRepos()
if err != nil { if err != nil {
err := util.NewErrBadRequest(errors.Errorf("failed to get user repositories from git source: %w", err)) err := util.NewAPIError(util.ErrBadRequest, errors.Errorf("failed to get user repositories from git source: %w", err))
httpError(w, err) util.HTTPError(w, err)
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -105,7 +105,7 @@ func (h *UserRemoteReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
for i, r := range remoteRepos { for i, r := range remoteRepos {
repos[i] = createRemoteRepoResponse(r) repos[i] = createRemoteRepoResponse(r)
} }
if err := httpResponse(w, http.StatusOK, repos); err != nil { if err := util.HTTPResponse(w, http.StatusOK, repos); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -44,7 +44,7 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
var req gwapitypes.CreateRemoteSourceRequest var req gwapitypes.CreateRemoteSourceRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -62,13 +62,13 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
LoginEnabled: req.LoginEnabled, LoginEnabled: req.LoginEnabled,
} }
rs, err := h.ah.CreateRemoteSource(ctx, creq) rs, err := h.ah.CreateRemoteSource(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createRemoteSourceResponse(rs) res := createRemoteSourceResponse(rs)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -90,7 +90,7 @@ func (h *UpdateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
var req gwapitypes.UpdateRemoteSourceRequest var req gwapitypes.UpdateRemoteSourceRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -108,13 +108,13 @@ func (h *UpdateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
LoginEnabled: req.LoginEnabled, LoginEnabled: req.LoginEnabled,
} }
rs, err := h.ah.UpdateRemoteSource(ctx, creq) rs, err := h.ah.UpdateRemoteSource(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createRemoteSourceResponse(rs) res := createRemoteSourceResponse(rs)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -145,13 +145,13 @@ func (h *RemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
rsRef := vars["remotesourceref"] rsRef := vars["remotesourceref"]
rs, err := h.ah.GetRemoteSource(ctx, rsRef) rs, err := h.ah.GetRemoteSource(ctx, rsRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createRemoteSourceResponse(rs) res := createRemoteSourceResponse(rs)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -175,12 +175,12 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxRunsLimit { if limit > MaxRunsLimit {
@ -199,7 +199,7 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Asc: asc, Asc: asc,
} }
csRemoteSources, err := h.ah.GetRemoteSources(ctx, areq) csRemoteSources, err := h.ah.GetRemoteSources(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -209,7 +209,7 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
remoteSources[i] = createRemoteSourceResponse(rs) remoteSources[i] = createRemoteSourceResponse(rs)
} }
if err := httpResponse(w, http.StatusOK, remoteSources); err != nil { if err := util.HTTPResponse(w, http.StatusOK, remoteSources); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -229,12 +229,12 @@ func (h *DeleteRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
rsRef := vars["remotesourceref"] rsRef := vars["remotesourceref"]
err := h.ah.DeleteRemoteSource(ctx, rsRef) err := h.ah.DeleteRemoteSource(ctx, rsRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -19,9 +19,10 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"go.uber.org/zap" util "agola.io/agola/internal/util"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"go.uber.org/zap"
) )
type ReposHandler struct { type ReposHandler struct {
@ -41,7 +42,7 @@ func (h *ReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
u, err := url.Parse(h.gitServerURL) u, err := url.Parse(h.gitServerURL)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
u.Path = path u.Path = path
@ -53,7 +54,7 @@ func (h *ReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
req = req.WithContext(ctx) req = req.WithContext(ctx)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
@ -67,7 +68,7 @@ func (h *ReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
@ -84,7 +85,7 @@ func (h *ReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// copy response body // copy response body
if _, err := io.Copy(w, resp.Body); err != nil { if _, err := io.Copy(w, resp.Body); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
} }

View File

@ -164,13 +164,13 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
runID := vars["runid"] runID := vars["runid"]
runResp, err := h.ah.GetRun(ctx, runID) runResp, err := h.ah.GetRun(ctx, runID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createRunResponse(runResp.Run, runResp.RunConfig) res := createRunResponse(runResp.Run, runResp.RunConfig)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -191,7 +191,7 @@ func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
taskID := vars["taskid"] taskID := vars["taskid"]
runResp, err := h.ah.GetRun(ctx, runID) runResp, err := h.ah.GetRun(ctx, runID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -201,13 +201,13 @@ func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
rt, ok := run.Tasks[taskID] rt, ok := run.Tasks[taskID]
if !ok { if !ok {
httpError(w, util.NewErrNotExist(errors.Errorf("run %q task %q not found", runID, taskID))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("run %q task %q not found", runID, taskID)))
return return
} }
rct := rc.Tasks[rt.ID] rct := rc.Tasks[rt.ID]
res := createRunTaskResponse(rt, rct) res := createRunTaskResponse(rt, rct)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -254,7 +254,7 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
group := q.Get("group") group := q.Get("group")
// we require that groups are specified to not return all runs // we require that groups are specified to not return all runs
if group == "" { if group == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("no groups specified"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("no groups specified")))
return return
} }
@ -269,12 +269,12 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxRunsLimit { if limit > MaxRunsLimit {
@ -298,7 +298,7 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Asc: asc, Asc: asc,
} }
runsResp, err := h.ah.GetRuns(ctx, areq) runsResp, err := h.ah.GetRuns(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -307,7 +307,7 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for i, r := range runsResp.Runs { for i, r := range runsResp.Runs {
runs[i] = createRunsResponse(r) runs[i] = createRunsResponse(r)
} }
if err := httpResponse(w, http.StatusOK, runs); err != nil { if err := util.HTTPResponse(w, http.StatusOK, runs); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -329,7 +329,7 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req gwapitypes.RunActionsRequest var req gwapitypes.RunActionsRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -340,13 +340,13 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
runResp, err := h.ah.RunAction(ctx, areq) runResp, err := h.ah.RunAction(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createRunResponse(runResp.Run, runResp.RunConfig) res := createRunResponse(runResp.Run, runResp.RunConfig)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -369,7 +369,7 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
var req gwapitypes.RunTaskActionsRequest var req gwapitypes.RunTaskActionsRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -380,7 +380,7 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
} }
err := h.ah.RunTaskAction(ctx, areq) err := h.ah.RunTaskAction(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -402,23 +402,23 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
runID := q.Get("runID") runID := q.Get("runID")
if runID == "" { if runID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("empty run id"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty run id")))
return return
} }
taskID := q.Get("taskID") taskID := q.Get("taskID")
if taskID == "" { if taskID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("empty task id"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty task id")))
return return
} }
_, setup := q["setup"] _, setup := q["setup"]
stepStr := q.Get("step") stepStr := q.Get("step")
if !setup && stepStr == "" { if !setup && stepStr == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("no setup or step number provided"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("no setup or step number provided")))
return return
} }
if setup && stepStr != "" { if setup && stepStr != "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("both setup and step number provided"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("both setup and step number provided")))
return return
} }
@ -427,7 +427,7 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
step, err = strconv.Atoi(stepStr) step, err = strconv.Atoi(stepStr)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse step number: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse step number: %w", err)))
return return
} }
} }
@ -446,7 +446,7 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
resp, err := h.ah.GetLogs(ctx, areq) resp, err := h.ah.GetLogs(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -519,23 +519,23 @@ func (h *LogsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
runID := q.Get("runID") runID := q.Get("runID")
if runID == "" { if runID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("empty run id"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty run id")))
return return
} }
taskID := q.Get("taskID") taskID := q.Get("taskID")
if taskID == "" { if taskID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("empty task id"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty task id")))
return return
} }
_, setup := q["setup"] _, setup := q["setup"]
stepStr := q.Get("step") stepStr := q.Get("step")
if !setup && stepStr == "" { if !setup && stepStr == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("no setup or step number provided"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("no setup or step number provided")))
return return
} }
if setup && stepStr != "" { if setup && stepStr != "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("both setup and step number provided"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("both setup and step number provided")))
return return
} }
@ -544,7 +544,7 @@ func (h *LogsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
step, err = strconv.Atoi(stepStr) step, err = strconv.Atoi(stepStr)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse step number: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse step number: %w", err)))
return return
} }
} }
@ -557,7 +557,7 @@ func (h *LogsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
err := h.ah.DeleteLogs(ctx, areq) err := h.ah.DeleteLogs(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }

View File

@ -52,7 +52,7 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, removeoverridden := query["removeoverridden"] _, removeoverridden := query["removeoverridden"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -64,7 +64,7 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
RemoveOverridden: removeoverridden, RemoveOverridden: removeoverridden,
} }
cssecrets, err := h.ah.GetSecrets(ctx, areq) cssecrets, err := h.ah.GetSecrets(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -74,7 +74,7 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
secrets[i] = createSecretResponse(s) secrets[i] = createSecretResponse(s)
} }
if err := httpResponse(w, http.StatusOK, secrets); err != nil { if err := util.HTTPResponse(w, http.StatusOK, secrets); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -91,14 +91,14 @@ func NewCreateSecretHandler(logger *zap.Logger, ah *action.ActionHandler) *Creat
func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
return return
} }
var req gwapitypes.CreateSecretRequest var req gwapitypes.CreateSecretRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -112,13 +112,13 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Path: req.Path, Path: req.Path,
} }
cssecret, err := h.ah.CreateSecret(ctx, areq) cssecret, err := h.ah.CreateSecret(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createSecretResponse(cssecret) res := createSecretResponse(cssecret)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -138,7 +138,7 @@ func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
secretName := vars["secretname"] secretName := vars["secretname"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -146,7 +146,7 @@ func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req gwapitypes.UpdateSecretRequest var req gwapitypes.UpdateSecretRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
areq := &action.UpdateSecretRequest{ areq := &action.UpdateSecretRequest{
@ -161,13 +161,13 @@ func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Path: req.Path, Path: req.Path,
} }
cssecret, err := h.ah.UpdateSecret(ctx, areq) cssecret, err := h.ah.UpdateSecret(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createSecretResponse(cssecret) res := createSecretResponse(cssecret)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -187,17 +187,17 @@ func (h *DeleteSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
secretName := vars["secretname"] secretName := vars["secretname"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
return return
} }
err = h.ah.DeleteSecret(ctx, parentType, parentRef, secretName) err = h.ah.DeleteSecret(ctx, parentType, parentRef, secretName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -48,7 +48,7 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req gwapitypes.CreateUserRequest var req gwapitypes.CreateUserRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -57,13 +57,13 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
u, err := h.ah.CreateUser(ctx, creq) u, err := h.ah.CreateUser(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createUserResponse(u) res := createUserResponse(u)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -83,12 +83,12 @@ func (h *DeleteUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
userRef := vars["userref"] userRef := vars["userref"]
err := h.ah.DeleteUser(ctx, userRef) err := h.ah.DeleteUser(ctx, userRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -107,18 +107,18 @@ func (h *CurrentUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
userID := common.CurrentUserID(ctx) userID := common.CurrentUserID(ctx)
if userID == "" { if userID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user not authenticated")))
return return
} }
user, err := h.ah.GetUser(ctx, userID) user, err := h.ah.GetUser(ctx, userID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createUserResponse(user) res := createUserResponse(user)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -138,13 +138,13 @@ func (h *UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
userRef := vars["userref"] userRef := vars["userref"]
user, err := h.ah.GetUser(ctx, userRef) user, err := h.ah.GetUser(ctx, userRef)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createUserResponse(user) res := createUserResponse(user)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -193,12 +193,12 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
limit, err = strconv.Atoi(limitS) limit, err = strconv.Atoi(limitS)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("cannot parse limit: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("cannot parse limit: %w", err)))
return return
} }
} }
if limit < 0 { if limit < 0 {
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("limit must be greater or equal than 0")))
return return
} }
if limit > MaxRunsLimit { if limit > MaxRunsLimit {
@ -217,7 +217,7 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Asc: asc, Asc: asc,
} }
csusers, err := h.ah.GetUsers(ctx, areq) csusers, err := h.ah.GetUsers(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -227,7 +227,7 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
users[i] = createUserResponse(p) users[i] = createUserResponse(p)
} }
if err := httpResponse(w, http.StatusOK, users); err != nil { if err := util.HTTPResponse(w, http.StatusOK, users); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -249,17 +249,17 @@ func (h *CreateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req *gwapitypes.CreateUserLARequest var req *gwapitypes.CreateUserLARequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
res, err := h.createUserLA(ctx, userRef, req) res, err := h.createUserLA(ctx, userRef, req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -311,12 +311,12 @@ func (h *DeleteUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
laID := vars["laid"] laID := vars["laid"]
err := h.ah.DeleteUserLA(ctx, userRef, laID) err := h.ah.DeleteUserLA(ctx, userRef, laID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -338,7 +338,7 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
var req gwapitypes.CreateUserTokenRequest var req gwapitypes.CreateUserTokenRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -348,7 +348,7 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
} }
h.log.Infof("creating user %q token", userRef) h.log.Infof("creating user %q token", userRef)
token, err := h.ah.CreateUserToken(ctx, creq) token, err := h.ah.CreateUserToken(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -357,7 +357,7 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
Token: token, Token: token,
} }
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -379,12 +379,12 @@ func (h *DeleteUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
h.log.Infof("deleting user %q token %q", userRef, tokenName) h.log.Infof("deleting user %q token %q", userRef, tokenName)
err := h.ah.DeleteUserToken(ctx, userRef, tokenName) err := h.ah.DeleteUserToken(ctx, userRef, tokenName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -404,17 +404,17 @@ func (h *RegisterUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req *gwapitypes.RegisterUserRequest var req *gwapitypes.RegisterUserRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
res, err := h.registerUser(ctx, req) res, err := h.registerUser(ctx, req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -455,17 +455,17 @@ func (h *AuthorizeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req *gwapitypes.LoginUserRequest var req *gwapitypes.LoginUserRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
res, err := h.authorize(ctx, req) res, err := h.authorize(ctx, req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -512,17 +512,17 @@ func (h *LoginUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req *gwapitypes.LoginUserRequest var req *gwapitypes.LoginUserRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
res, err := h.loginUser(ctx, req) res, err := h.loginUser(ctx, req)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -566,7 +566,7 @@ func (h *UserCreateRunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
var req gwapitypes.UserCreateRunRequest var req gwapitypes.UserCreateRunRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -582,12 +582,12 @@ func (h *UserCreateRunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
Variables: req.Variables, Variables: req.Variables,
} }
err := h.ah.UserCreateRun(ctx, creq) err := h.ah.UserCreateRun(ctx, creq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusCreated, nil); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -606,12 +606,12 @@ func (h *UserOrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
userID := common.CurrentUserID(ctx) userID := common.CurrentUserID(ctx)
if userID == "" { if userID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("user not authenticated")))
return return
} }
userOrgs, err := h.ah.GetUserOrgs(ctx, userID) userOrgs, err := h.ah.GetUserOrgs(ctx, userID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -621,7 +621,7 @@ func (h *UserOrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
res[i] = createUserOrgsResponse(userOrg) res[i] = createUserOrgsResponse(userOrg)
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -69,7 +69,7 @@ func (h *VariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, removeoverridden := query["removeoverridden"] _, removeoverridden := query["removeoverridden"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -81,7 +81,7 @@ func (h *VariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
RemoveOverridden: removeoverridden, RemoveOverridden: removeoverridden,
} }
csvars, cssecrets, err := h.ah.GetVariables(ctx, areq) csvars, cssecrets, err := h.ah.GetVariables(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -91,7 +91,7 @@ func (h *VariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
variables[i] = createVariableResponse(v, cssecrets) variables[i] = createVariableResponse(v, cssecrets)
} }
if err := httpResponse(w, http.StatusOK, variables); err != nil { if err := util.HTTPResponse(w, http.StatusOK, variables); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -108,7 +108,7 @@ func NewCreateVariableHandler(logger *zap.Logger, ah *action.ActionHandler) *Cre
func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -116,7 +116,7 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
var req gwapitypes.CreateVariableRequest var req gwapitypes.CreateVariableRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
areq := &action.CreateVariableRequest{ areq := &action.CreateVariableRequest{
@ -126,13 +126,13 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
Values: fromApiVariableValues(req.Values), Values: fromApiVariableValues(req.Values),
} }
csvar, cssecrets, err := h.ah.CreateVariable(ctx, areq) csvar, cssecrets, err := h.ah.CreateVariable(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createVariableResponse(csvar, cssecrets) res := createVariableResponse(csvar, cssecrets)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -152,7 +152,7 @@ func (h *UpdateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
variableName := vars["variablename"] variableName := vars["variablename"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
@ -160,7 +160,7 @@ func (h *UpdateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
var req gwapitypes.UpdateVariableRequest var req gwapitypes.UpdateVariableRequest
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil { if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err)) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, err))
return return
} }
@ -173,13 +173,13 @@ func (h *UpdateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
Values: fromApiVariableValues(req.Values), Values: fromApiVariableValues(req.Values),
} }
csvar, cssecrets, err := h.ah.UpdateVariable(ctx, areq) csvar, cssecrets, err := h.ah.UpdateVariable(ctx, areq)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
res := createVariableResponse(csvar, cssecrets) res := createVariableResponse(csvar, cssecrets)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -199,18 +199,18 @@ func (h *DeleteVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
variableName := vars["variablename"] variableName := vars["variablename"]
parentType, parentRef, err := GetConfigTypeRef(r) parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
err = h.ah.DeleteVariable(ctx, parentType, parentRef, variableName) err = h.ah.DeleteVariable(ctx, parentType, parentRef, variableName)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusNoContent, nil); err != nil { if err := util.HTTPResponse(w, http.StatusNoContent, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -18,6 +18,7 @@ import (
"net/http" "net/http"
"agola.io/agola/internal/services/gateway/action" "agola.io/agola/internal/services/gateway/action"
util "agola.io/agola/internal/util"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -35,12 +36,12 @@ func (h *VersionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
version, err := h.ah.GetVersion(ctx) version, err := h.ah.GetVersion(ctx)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, version); err != nil { if err := util.HTTPResponse(w, http.StatusOK, version); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -48,12 +48,12 @@ func NewWebhooksHandler(logger *zap.Logger, ah *action.ActionHandler, configstor
func (h *webhooksHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *webhooksHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := h.handleWebhook(r) err := h.handleWebhook(r)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, nil); err != nil { if err := util.HTTPResponse(w, http.StatusOK, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -63,33 +63,33 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) error {
projectID := r.URL.Query().Get("projectid") projectID := r.URL.Query().Get("projectid")
if projectID == "" { if projectID == "" {
return util.NewErrBadRequest(errors.Errorf("bad webhook url %q. Missing projectid", r.URL)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("bad webhook url %q. Missing projectid", r.URL))
} }
defer r.Body.Close() defer r.Body.Close()
csProject, _, err := h.configstoreClient.GetProject(ctx, projectID) csProject, _, err := h.configstoreClient.GetProject(ctx, projectID)
if err != nil { if err != nil {
return util.NewErrBadRequest(errors.Errorf("failed to get project %s: %w", projectID, err)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("failed to get project %s: %w", projectID, err))
} }
project := csProject.Project project := csProject.Project
user, _, err := h.configstoreClient.GetUserByLinkedAccount(ctx, project.LinkedAccountID) user, _, err := h.configstoreClient.GetUserByLinkedAccount(ctx, project.LinkedAccountID)
if err != nil { if err != nil {
return util.NewErrInternal(errors.Errorf("failed to get user by linked account %q: %w", project.LinkedAccountID, err)) return util.NewAPIError(util.ErrInternal, errors.Errorf("failed to get user by linked account %q: %w", project.LinkedAccountID, err))
} }
la := user.LinkedAccounts[project.LinkedAccountID] la := user.LinkedAccounts[project.LinkedAccountID]
if la == nil { if la == nil {
return util.NewErrInternal(errors.Errorf("linked account %q in user %q doesn't exist", project.LinkedAccountID, user.Name)) return util.NewAPIError(util.ErrInternal, errors.Errorf("linked account %q in user %q doesn't exist", project.LinkedAccountID, user.Name))
} }
rs, _, err := h.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID) rs, _, err := h.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID)
if err != nil { if err != nil {
return util.NewErrInternal(errors.Errorf("failed to get remote source %q: %w", la.RemoteSourceID, err)) return util.NewAPIError(util.ErrInternal, errors.Errorf("failed to get remote source %q: %w", la.RemoteSourceID, err))
} }
gitSource, err := h.ah.GetGitSource(ctx, rs, user.Name, la) gitSource, err := h.ah.GetGitSource(ctx, rs, user.Name, la)
if err != nil { if err != nil {
return util.NewErrInternal(errors.Errorf("failed to create gitea client: %w", err)) return util.NewAPIError(util.ErrInternal, errors.Errorf("failed to create gitea client: %w", err))
} }
sshPrivKey := project.SSHPrivateKey sshPrivKey := project.SSHPrivateKey
@ -102,7 +102,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) error {
webhookData, err := gitSource.ParseWebhook(r, project.WebhookSecret) webhookData, err := gitSource.ParseWebhook(r, project.WebhookSecret)
if err != nil { if err != nil {
return util.NewErrBadRequest(errors.Errorf("failed to parse webhook: %w", err)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("failed to parse webhook: %w", err))
} }
// skip nil webhook data // skip nil webhook data
// TODO(sgotti) report the reason of the skip // TODO(sgotti) report the reason of the skip
@ -141,7 +141,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) error {
CompareLink: webhookData.CompareLink, CompareLink: webhookData.CompareLink,
} }
if err := h.ah.CreateRuns(ctx, req); err != nil { if err := h.ah.CreateRuns(ctx, req); err != nil {
return util.NewErrInternal(errors.Errorf("failed to create run: %w", err)) return util.NewAPIError(util.ErrInternal, errors.Errorf("failed to create run: %w", err))
} }
return nil return nil

View File

@ -21,6 +21,7 @@ import (
scommon "agola.io/agola/internal/services/common" scommon "agola.io/agola/internal/services/common"
"agola.io/agola/internal/services/gateway/common" "agola.io/agola/internal/services/gateway/common"
"agola.io/agola/internal/util"
csclient "agola.io/agola/services/configstore/client" csclient "agola.io/agola/services/configstore/client"
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt/v4"
@ -64,12 +65,12 @@ func (h *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.next.ServeHTTP(w, r.WithContext(ctx)) h.next.ServeHTTP(w, r.WithContext(ctx))
return return
} else { } else {
user, resp, err := h.configstoreClient.GetUserByToken(ctx, tokenString) user, _, err := h.configstoreClient.GetUserByToken(ctx, tokenString)
if err != nil && resp.StatusCode == http.StatusNotFound { if err != nil {
if util.RemoteErrorIs(err, util.ErrNotExist) {
http.Error(w, "", http.StatusUnauthorized) http.Error(w, "", http.StatusUnauthorized)
return return
} }
if err != nil {
http.Error(w, "", http.StatusInternalServerError) http.Error(w, "", http.StatusInternalServerError)
return return
} }
@ -118,9 +119,9 @@ func (h *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
claims := token.Claims.(jwt.MapClaims) claims := token.Claims.(jwt.MapClaims)
userID := claims["sub"].(string) userID := claims["sub"].(string)
user, resp, err := h.configstoreClient.GetUser(ctx, userID) user, _, err := h.configstoreClient.GetUser(ctx, userID)
if err != nil { if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound { if util.RemoteErrorIs(err, util.ErrNotExist) {
http.Error(w, "", http.StatusUnauthorized) http.Error(w, "", http.StatusUnauthorized)
return return
} }

View File

@ -179,13 +179,13 @@ func (h *ActionHandler) newRun(ctx context.Context, req *RunCreateRequest) (*typ
setupErrors := req.SetupErrors setupErrors := req.SetupErrors
if req.Group == "" { if req.Group == "" {
return nil, util.NewErrBadRequest(errors.Errorf("run group is empty")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("run group is empty"))
} }
if !path.IsAbs(req.Group) { if !path.IsAbs(req.Group) {
return nil, util.NewErrBadRequest(errors.Errorf("run group %q must be an absolute path", req.Group)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("run group %q must be an absolute path", req.Group))
} }
if req.RunConfigTasks == nil && len(setupErrors) == 0 { if req.RunConfigTasks == nil && len(setupErrors) == 0 {
return nil, util.NewErrBadRequest(errors.Errorf("empty run config tasks and setup errors")) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("empty run config tasks and setup errors"))
} }
// generate a new run sequence that will be the same for the run and runconfig // generate a new run sequence that will be the same for the run and runconfig
@ -241,7 +241,7 @@ func (h *ActionHandler) recreateRun(ctx context.Context, req *RunCreateRequest)
h.log.Infof("creating run from existing run") h.log.Infof("creating run from existing run")
rc, err := store.OSTGetRunConfig(h.dm, req.RunID) rc, err := store.OSTGetRunConfig(h.dm, req.RunID)
if err != nil { if err != nil {
return nil, util.NewErrBadRequest(errors.Errorf("runconfig %q doesn't exist: %w", req.RunID, err)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("runconfig %q doesn't exist: %w", req.RunID, err))
} }
run, err := store.GetRunEtcdOrOST(ctx, h.e, h.dm, req.RunID) run, err := store.GetRunEtcdOrOST(ctx, h.e, h.dm, req.RunID)
@ -249,7 +249,7 @@ func (h *ActionHandler) recreateRun(ctx context.Context, req *RunCreateRequest)
return nil, err return nil, err
} }
if run == nil { if run == nil {
return nil, util.NewErrBadRequest(errors.Errorf("run %q doesn't exist: %w", req.RunID, err)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("run %q doesn't exist: %w", req.RunID, err))
} }
h.log.Debugf("rc: %s", util.Dump(rc)) h.log.Debugf("rc: %s", util.Dump(rc))
@ -257,11 +257,11 @@ func (h *ActionHandler) recreateRun(ctx context.Context, req *RunCreateRequest)
if req.FromStart { if req.FromStart {
if canRestart, reason := run.CanRestartFromScratch(); !canRestart { if canRestart, reason := run.CanRestartFromScratch(); !canRestart {
return nil, util.NewErrBadRequest(errors.Errorf("run cannot be restarted: %s", reason)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("run cannot be restarted: %s", reason))
} }
} else { } else {
if canRestart, reason := run.CanRestartFromFailedTasks(); !canRestart { if canRestart, reason := run.CanRestartFromFailedTasks(); !canRestart {
return nil, util.NewErrBadRequest(errors.Errorf("run cannot be restarted: %s", reason)) return nil, util.NewAPIError(util.ErrBadRequest, errors.Errorf("run cannot be restarted: %s", reason))
} }
} }
@ -510,7 +510,7 @@ func (h *ActionHandler) RunTaskSetAnnotations(ctx context.Context, req *RunTaskS
task, ok := r.Tasks[req.TaskID] task, ok := r.Tasks[req.TaskID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("run %q doesn't have task %q", r.ID, req.TaskID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("run %q doesn't have task %q", r.ID, req.TaskID))
} }
task.Annotations = req.Annotations task.Annotations = req.Annotations
@ -538,15 +538,15 @@ func (h *ActionHandler) ApproveRunTask(ctx context.Context, req *RunTaskApproveR
task, ok := r.Tasks[req.TaskID] task, ok := r.Tasks[req.TaskID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("run %q doesn't have task %q", r.ID, req.TaskID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("run %q doesn't have task %q", r.ID, req.TaskID))
} }
if !task.WaitingApproval { if !task.WaitingApproval {
return util.NewErrBadRequest(errors.Errorf("run %q, task %q is not in waiting approval state", r.ID, req.TaskID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("run %q, task %q is not in waiting approval state", r.ID, req.TaskID))
} }
if task.Approved { if task.Approved {
return util.NewErrBadRequest(errors.Errorf("run %q, task %q is already approved", r.ID, req.TaskID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("run %q, task %q is already approved", r.ID, req.TaskID))
} }
task.WaitingApproval = false task.WaitingApproval = false
@ -595,7 +595,7 @@ func (h *ActionHandler) GetExecutorTask(ctx context.Context, etID string) (*type
return nil, err return nil, err
} }
if et == nil { if et == nil {
return nil, util.NewErrNotExist(errors.Errorf("executor task %q not found", etID)) return nil, util.NewAPIError(util.ErrNotExist, errors.Errorf("executor task %q not found", etID))
} }
r, _, err := store.GetRun(ctx, h.e, et.Spec.RunID) r, _, err := store.GetRun(ctx, h.e, et.Spec.RunID)

View File

@ -32,10 +32,10 @@ func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error
} }
if enable && len(resp.Kvs) > 0 { if enable && len(resp.Kvs) > 0 {
return util.NewErrBadRequest(errors.Errorf("maintenance mode already enabled")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("maintenance mode already enabled"))
} }
if !enable && len(resp.Kvs) == 0 { if !enable && len(resp.Kvs) == 0 {
return util.NewErrBadRequest(errors.Errorf("maintenance mode already disabled")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("maintenance mode already disabled"))
} }
if enable { if enable {
@ -67,7 +67,7 @@ func (h *ActionHandler) Export(ctx context.Context, w io.Writer) error {
func (h *ActionHandler) Import(ctx context.Context, r io.Reader) error { func (h *ActionHandler) Import(ctx context.Context, r io.Reader) error {
if !h.maintenanceMode { if !h.maintenanceMode {
return util.NewErrBadRequest(errors.Errorf("not in maintenance mode")) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("not in maintenance mode"))
} }
return h.dm.Import(ctx, r) return h.dm.Import(ctx, r)
} }

View File

@ -46,92 +46,6 @@ type ErrorResponse struct {
Message string `json:"message"` Message string `json:"message"`
} }
func ErrorResponseFromError(err error) *ErrorResponse {
var aerr error
// use inner errors if of these types
switch {
case util.IsBadRequest(err):
var cerr *util.ErrBadRequest
errors.As(err, &cerr)
aerr = cerr
case util.IsNotExist(err):
var cerr *util.ErrNotExist
errors.As(err, &cerr)
aerr = cerr
case util.IsForbidden(err):
var cerr *util.ErrForbidden
errors.As(err, &cerr)
aerr = cerr
case util.IsUnauthorized(err):
var cerr *util.ErrUnauthorized
errors.As(err, &cerr)
aerr = cerr
case util.IsInternal(err):
var cerr *util.ErrInternal
errors.As(err, &cerr)
aerr = cerr
}
if aerr != nil {
return &ErrorResponse{Message: aerr.Error()}
}
// on generic error return an generic message to not leak the real error
return &ErrorResponse{Message: "internal server error"}
}
func httpError(w http.ResponseWriter, err error) bool {
if err == nil {
return false
}
response := ErrorResponseFromError(err)
resj, merr := json.Marshal(response)
if merr != nil {
w.WriteHeader(http.StatusInternalServerError)
return true
}
switch {
case util.IsBadRequest(err):
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write(resj)
case util.IsNotExist(err):
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write(resj)
case util.IsForbidden(err):
w.WriteHeader(http.StatusForbidden)
_, _ = w.Write(resj)
case util.IsUnauthorized(err):
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write(resj)
case util.IsInternal(err):
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write(resj)
default:
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write(resj)
}
return true
}
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
w.Header().Set("Content-Type", "application/json")
if res != nil {
resj, err := json.Marshal(res)
if err != nil {
httpError(w, err)
return err
}
w.WriteHeader(code)
_, err = w.Write(resj)
return err
}
w.WriteHeader(code)
return nil
}
type LogsHandler struct { type LogsHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
e *etcd.Store e *etcd.Store
@ -194,10 +108,10 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
if sendError { if sendError {
switch { switch {
case util.IsNotExist(err): case util.APIErrorIs(err, util.ErrNotExist):
httpError(w, util.NewErrNotExist(errors.Errorf("log doesn't exist: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("log doesn't exist: %w", err)))
default: default:
httpError(w, err) util.HTTPError(w, err)
} }
} }
} }
@ -209,15 +123,15 @@ func (h *LogsHandler) readTaskLogs(ctx context.Context, runID, taskID string, se
return err, true return err, true
} }
if r == nil { if r == nil {
return util.NewErrNotExist(errors.Errorf("no such run with id: %s", runID)), true return util.NewAPIError(util.ErrNotExist, errors.Errorf("no such run with id: %s", runID)), true
} }
task, ok := r.Tasks[taskID] task, ok := r.Tasks[taskID]
if !ok { if !ok {
return util.NewErrNotExist(errors.Errorf("no such task with ID %s in run %s", taskID, runID)), true return util.NewAPIError(util.ErrNotExist, errors.Errorf("no such task with ID %s in run %s", taskID, runID)), true
} }
if len(task.Steps) <= step { if len(task.Steps) <= step {
return util.NewErrNotExist(errors.Errorf("no such step for task %s in run %s", taskID, runID)), true return util.NewAPIError(util.ErrNotExist, errors.Errorf("no such step for task %s in run %s", taskID, runID)), true
} }
// if the log has been already fetched use it, otherwise fetch it from the executor // if the log has been already fetched use it, otherwise fetch it from the executor
@ -231,7 +145,7 @@ func (h *LogsHandler) readTaskLogs(ctx context.Context, runID, taskID string, se
f, err := h.ost.ReadObject(logPath) f, err := h.ost.ReadObject(logPath)
if err != nil { if err != nil {
if objectstorage.IsNotExist(err) { if objectstorage.IsNotExist(err) {
return util.NewErrNotExist(err), true return util.NewAPIError(util.ErrNotExist, err), true
} }
return err, true return err, true
} }
@ -242,14 +156,14 @@ func (h *LogsHandler) readTaskLogs(ctx context.Context, runID, taskID string, se
et, err := store.GetExecutorTask(ctx, h.e, task.ID) et, err := store.GetExecutorTask(ctx, h.e, task.ID)
if err != nil { if err != nil {
if errors.Is(err, etcd.ErrKeyNotFound) { if errors.Is(err, etcd.ErrKeyNotFound) {
return util.NewErrNotExist(errors.Errorf("executor task with id %q doesn't exist", task.ID)), true return util.NewAPIError(util.ErrNotExist, errors.Errorf("executor task with id %q doesn't exist", task.ID)), true
} }
return err, true return err, true
} }
executor, err := store.GetExecutor(ctx, h.e, et.Spec.ExecutorID) executor, err := store.GetExecutor(ctx, h.e, et.Spec.ExecutorID)
if err != nil { if err != nil {
if errors.Is(err, etcd.ErrKeyNotFound) { if errors.Is(err, etcd.ErrKeyNotFound) {
return util.NewErrNotExist(errors.Errorf("executor with id %q doesn't exist", et.Spec.ExecutorID)), true return util.NewAPIError(util.ErrNotExist, errors.Errorf("executor with id %q doesn't exist", et.Spec.ExecutorID)), true
} }
return err, true return err, true
} }
@ -270,7 +184,7 @@ func (h *LogsHandler) readTaskLogs(ctx context.Context, runID, taskID string, se
defer req.Body.Close() defer req.Body.Close()
if req.StatusCode != http.StatusOK { if req.StatusCode != http.StatusOK {
if req.StatusCode == http.StatusNotFound { if req.StatusCode == http.StatusNotFound {
return util.NewErrNotExist(errors.New("no log on executor")), true return util.NewAPIError(util.ErrNotExist, errors.New("no log on executor")), true
} }
return errors.Errorf("received http status: %d", req.StatusCode), true return errors.Errorf("received http status: %d", req.StatusCode), true
} }
@ -346,23 +260,23 @@ func (h *LogsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
runID := q.Get("runid") runID := q.Get("runid")
if runID == "" { if runID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("runid is empty"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("runid is empty")))
return return
} }
taskID := q.Get("taskid") taskID := q.Get("taskid")
if taskID == "" { if taskID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("taskid is empty"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("taskid is empty")))
return return
} }
_, setup := q["setup"] _, setup := q["setup"]
stepStr := q.Get("step") stepStr := q.Get("step")
if !setup && stepStr == "" { if !setup && stepStr == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("setup is false and step is empty"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("setup is false and step is empty")))
return return
} }
if setup && stepStr != "" { if setup && stepStr != "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("setup is true and step is %s", stepStr))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("setup is true and step is %s", stepStr)))
return return
} }
@ -371,7 +285,7 @@ func (h *LogsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var err error var err error
step, err = strconv.Atoi(stepStr) step, err = strconv.Atoi(stepStr)
if err != nil { if err != nil {
httpError(w, util.NewErrBadRequest(errors.Errorf("step %s is not a valid number", stepStr))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("step %s is not a valid number", stepStr)))
return return
} }
} }
@ -379,10 +293,10 @@ func (h *LogsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := h.deleteTaskLogs(ctx, runID, taskID, setup, step, w); err != nil { if err := h.deleteTaskLogs(ctx, runID, taskID, setup, step, w); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
switch { switch {
case util.IsNotExist(err): case util.APIErrorIs(err, util.ErrNotExist):
httpError(w, util.NewErrNotExist(errors.Errorf("log doesn't exist: %w", err))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("log doesn't exist: %w", err)))
default: default:
httpError(w, err) util.HTTPError(w, err)
} }
} }
} }
@ -393,15 +307,15 @@ func (h *LogsDeleteHandler) deleteTaskLogs(ctx context.Context, runID, taskID st
return err return err
} }
if r == nil { if r == nil {
return util.NewErrNotExist(errors.Errorf("no such run with id: %s", runID)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("no such run with id: %s", runID))
} }
task, ok := r.Tasks[taskID] task, ok := r.Tasks[taskID]
if !ok { if !ok {
return util.NewErrNotExist(errors.Errorf("no such task with ID %s in run %s", taskID, runID)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("no such task with ID %s in run %s", taskID, runID))
} }
if len(task.Steps) <= step { if len(task.Steps) <= step {
return util.NewErrNotExist(errors.Errorf("no such step for task %s in run %s", taskID, runID)) return util.NewAPIError(util.ErrNotExist, errors.Errorf("no such step for task %s in run %s", taskID, runID))
} }
if task.Steps[step].LogPhase == types.RunTaskFetchPhaseFinished { if task.Steps[step].LogPhase == types.RunTaskFetchPhaseFinished {
@ -414,13 +328,13 @@ func (h *LogsDeleteHandler) deleteTaskLogs(ctx context.Context, runID, taskID st
err := h.ost.DeleteObject(logPath) err := h.ost.DeleteObject(logPath)
if err != nil { if err != nil {
if objectstorage.IsNotExist(err) { if objectstorage.IsNotExist(err) {
return util.NewErrNotExist(err) return util.NewAPIError(util.ErrNotExist, err)
} }
return err return err
} }
return nil return nil
} }
return util.NewErrBadRequest(errors.Errorf("Log for task %s in run %s is not yet archived", taskID, runID)) return util.NewAPIError(util.ErrBadRequest, errors.Errorf("Log for task %s in run %s is not yet archived", taskID, runID))
} }
type ChangeGroupsUpdateTokensHandler struct { type ChangeGroupsUpdateTokensHandler struct {
@ -458,7 +372,7 @@ func (h *ChangeGroupsUpdateTokensHandler) ServeHTTP(w http.ResponseWriter, r *ht
return return
} }
if err := httpResponse(w, http.StatusOK, cgts); err != nil { if err := util.HTTPResponse(w, http.StatusOK, cgts); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -506,7 +420,7 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
if run == nil { if run == nil {
httpError(w, util.NewErrNotExist(errors.Errorf("run %q doesn't exist", runID))) util.HTTPError(w, util.NewAPIError(util.ErrNotExist, errors.Errorf("run %q doesn't exist", runID)))
return return
} }
@ -528,7 +442,7 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ChangeGroupsUpdateToken: cgts, ChangeGroupsUpdateToken: cgts,
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -613,7 +527,7 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Runs: runs, Runs: runs,
ChangeGroupsUpdateToken: cgts, ChangeGroupsUpdateToken: cgts,
} }
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := util.HTTPResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -659,7 +573,7 @@ func (h *RunCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
rb, err := h.ah.CreateRun(ctx, creq) rb, err := h.ah.CreateRun(ctx, creq)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
@ -668,7 +582,7 @@ func (h *RunCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
RunConfig: rb.Rc, RunConfig: rb.Rc,
} }
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := util.HTTPResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -706,7 +620,7 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
if err := h.ah.ChangeRunPhase(ctx, creq); err != nil { if err := h.ah.ChangeRunPhase(ctx, creq); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
case rsapitypes.RunActionTypeStop: case rsapitypes.RunActionTypeStop:
@ -716,7 +630,7 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
if err := h.ah.StopRun(ctx, creq); err != nil { if err := h.ah.StopRun(ctx, creq); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
default: default:
@ -760,7 +674,7 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
} }
if err := h.ah.RunTaskSetAnnotations(ctx, creq); err != nil { if err := h.ah.RunTaskSetAnnotations(ctx, creq); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
@ -772,7 +686,7 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
} }
if err := h.ah.ApproveRunTask(ctx, creq); err != nil { if err := h.ah.ApproveRunTask(ctx, creq); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }

View File

@ -153,17 +153,17 @@ func (h *ExecutorTaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
// TODO(sgotti) Check authorized call from executors // TODO(sgotti) Check authorized call from executors
etID := vars["taskid"] etID := vars["taskid"]
if etID == "" { if etID == "" {
httpError(w, util.NewErrBadRequest(errors.Errorf("taskid is empty"))) util.HTTPError(w, util.NewAPIError(util.ErrBadRequest, errors.Errorf("taskid is empty")))
return return
} }
et, err := h.ah.GetExecutorTask(ctx, etID) et, err := h.ah.GetExecutorTask(ctx, etID)
if httpError(w, err) { if util.HTTPError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
if err := httpResponse(w, http.StatusOK, et); err != nil { if err := util.HTTPResponse(w, http.StatusOK, et); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -235,7 +235,7 @@ func (h *ArchivesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := h.readArchive(taskID, step, w); err != nil { if err := h.readArchive(taskID, step, w); err != nil {
switch { switch {
case util.IsNotExist(err): case util.APIErrorIs(err, util.ErrNotExist):
http.Error(w, err.Error(), http.StatusNotFound) http.Error(w, err.Error(), http.StatusNotFound)
default: default:
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
@ -249,7 +249,7 @@ func (h *ArchivesHandler) readArchive(rtID string, step int, w io.Writer) error
f, err := h.ost.ReadObject(archivePath) f, err := h.ost.ReadObject(archivePath)
if err != nil { if err != nil {
if objectstorage.IsNotExist(err) { if objectstorage.IsNotExist(err) {
return util.NewErrNotExist(err) return util.NewAPIError(util.ErrNotExist, err)
} }
return err return err
} }
@ -308,7 +308,7 @@ func (h *CacheHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := h.readCache(matchedKey, w); err != nil { if err := h.readCache(matchedKey, w); err != nil {
switch { switch {
case util.IsNotExist(err): case util.APIErrorIs(err, util.ErrNotExist):
http.Error(w, err.Error(), http.StatusNotFound) http.Error(w, err.Error(), http.StatusNotFound)
default: default:
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
@ -358,7 +358,7 @@ func (h *CacheHandler) readCache(key string, w io.Writer) error {
f, err := h.ost.ReadObject(cachePath) f, err := h.ost.ReadObject(cachePath)
if err != nil { if err != nil {
if objectstorage.IsNotExist(err) { if objectstorage.IsNotExist(err) {
return util.NewErrNotExist(err) return util.NewAPIError(util.ErrNotExist, err)
} }
return err return err
} }

View File

@ -19,6 +19,7 @@ import (
"agola.io/agola/internal/etcd" "agola.io/agola/internal/etcd"
"agola.io/agola/internal/services/runservice/action" "agola.io/agola/internal/services/runservice/action"
"agola.io/agola/internal/util"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -47,11 +48,11 @@ func (h *MaintenanceModeHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
err := h.ah.MaintenanceMode(ctx, enable) err := h.ah.MaintenanceMode(ctx, enable)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, nil); err != nil { if err := util.HTTPResponse(w, http.StatusOK, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
@ -96,11 +97,11 @@ func (h *ImportHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := h.ah.Import(ctx, r.Body) err := h.ah.Import(ctx, r.Body)
if err != nil { if err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
httpError(w, err) util.HTTPError(w, err)
return return
} }
if err := httpResponse(w, http.StatusOK, nil); err != nil { if err := util.HTTPResponse(w, http.StatusOK, nil); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }

View File

@ -24,7 +24,6 @@ import (
"agola.io/agola/internal/datamanager" "agola.io/agola/internal/datamanager"
"agola.io/agola/internal/etcd" "agola.io/agola/internal/etcd"
"agola.io/agola/internal/objectstorage"
"agola.io/agola/internal/services/runservice/common" "agola.io/agola/internal/services/runservice/common"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
"agola.io/agola/services/runservice/types" "agola.io/agola/services/runservice/types"
@ -527,7 +526,7 @@ func GetRunEtcdOrOST(ctx context.Context, e *etcd.Store, dm *datamanager.DataMan
} }
if r == nil { if r == nil {
r, err = OSTGetRun(dm, runID) r, err = OSTGetRun(dm, runID)
if err != nil && !objectstorage.IsNotExist(err) { if err != nil && !datamanager.IsNotExist(err) {
return nil, err return nil, err
} }
} }

View File

@ -163,7 +163,7 @@ func (s *Scheduler) approveRunTasks(ctx context.Context, runID string) error {
for _, rtID := range tasksWaitingApproval { for _, rtID := range tasksWaitingApproval {
rt, ok := run.Tasks[rtID] rt, ok := run.Tasks[rtID]
if !ok { if !ok {
return util.NewErrBadRequest(errors.Errorf("run %q doesn't have task %q", run.ID, rtID)) return errors.Errorf("run %q doesn't have task %q", run.ID, rtID)
} }
annotations := rt.Annotations annotations := rt.Annotations
if annotations == nil { if annotations == nil {

View File

@ -15,9 +15,9 @@
package util package util
import ( import (
"errors"
"fmt"
"strings" "strings"
errors "golang.org/x/xerrors"
) )
// Errors is an error that contains multiple errors // Errors is an error that contains multiple errors
@ -59,116 +59,130 @@ func (e *Errors) Equal(e2 error) bool {
return CompareStringSliceNoOrder(errs1, errs2) return CompareStringSliceNoOrder(errs1, errs2)
} }
// ErrBadRequest represent an error caused by a bad command request type ErrorKind int
// it's used to differentiate an internal error from an user error type ErrorCode string
type ErrBadRequest struct {
Err error const (
ErrBadRequest ErrorKind = iota
ErrNotExist
ErrForbidden
ErrUnauthorized
ErrInternal
)
func (k ErrorKind) String() string {
switch k {
case ErrBadRequest:
return "badrequest"
case ErrNotExist:
return "notexist"
case ErrForbidden:
return "forbidden"
case ErrUnauthorized:
return "unauthorized"
case ErrInternal:
return "internal"
} }
func (e *ErrBadRequest) Error() string { return "unknown"
return e.Err.Error()
} }
func NewErrBadRequest(err error) *ErrBadRequest { type APIError struct {
return &ErrBadRequest{Err: err} err error
Kind ErrorKind
Code ErrorCode
Message string
} }
func (e *ErrBadRequest) Unwrap() error { func NewAPIError(kind ErrorKind, err error, options ...APIErrorOption) error {
return e.Err derr := &APIError{err: err, Kind: kind}
for _, opt := range options {
opt(derr)
} }
func IsBadRequest(err error) bool { return derr
var e *ErrBadRequest
return errors.As(err, &e)
} }
// ErrNotExist represent a not exist error func (e *APIError) Error() string {
// it's used to differentiate an internal error from an user error return e.err.Error()
type ErrNotExist struct {
Err error
} }
func (e *ErrNotExist) Error() string { func (e *APIError) Unwrap() error {
return e.Err.Error() return e.err
} }
func NewErrNotExist(err error) *ErrNotExist { type APIErrorOption func(e *APIError)
return &ErrNotExist{Err: err}
func WithCode(code ErrorCode) APIErrorOption {
return func(e *APIError) {
e.Code = code
}
} }
func (e *ErrNotExist) Unwrap() error { func WithMessage(message string) APIErrorOption {
return e.Err return func(e *APIError) {
e.Message = message
}
} }
func IsNotExist(err error) bool { func AsAPIError(err error) (*APIError, bool) {
var e *ErrNotExist var derr *APIError
return errors.As(err, &e) return derr, errors.As(err, &derr)
} }
// ErrForbidden represent an error caused by an forbidden operation func APIErrorIs(err error, kind ErrorKind) bool {
// it's used to differentiate an internal error from an user error if derr, ok := AsAPIError(err); ok && derr.Kind == kind {
type ErrForbidden struct { return true
Err error
} }
func (e *ErrForbidden) Error() string { return false
return e.Err.Error()
} }
func NewErrForbidden(err error) *ErrForbidden { // RemoteError is an error received from a remote call. It's similar to
return &ErrForbidden{Err: err} // APIError but with another type so it can be distinguished and won't be
// propagated to the api response.
type RemoteError struct {
Kind ErrorKind
Code string
Message string
} }
func (e *ErrForbidden) Unwrap() error { func NewRemoteError(kind ErrorKind, code string, message string) error {
return e.Err return &RemoteError{Kind: kind, Code: code, Message: message}
} }
func IsForbidden(err error) bool { func (e *RemoteError) Error() string {
var e *ErrForbidden code := e.Code
return errors.As(err, &e) message := e.Message
errStr := fmt.Sprintf("remote error %s", e.Kind)
if code != "" {
errStr += fmt.Sprintf(" (code: %s)", code)
}
if message != "" {
errStr += fmt.Sprintf(" (message: %s)", message)
} }
// ErrUnauthorized represent an error caused by an unauthorized request return errStr
// it's used to differentiate an internal error from an user error
type ErrUnauthorized struct {
Err error
} }
func (e *ErrUnauthorized) Error() string { func AsRemoteError(err error) (*RemoteError, bool) {
return e.Err.Error() var rerr *RemoteError
return rerr, errors.As(err, &rerr)
} }
func NewErrUnauthorized(err error) *ErrUnauthorized { func RemoteErrorIs(err error, kind ErrorKind) bool {
return &ErrUnauthorized{Err: err} if rerr, ok := AsRemoteError(err); ok && rerr.Kind == kind {
return true
} }
func (e *ErrUnauthorized) Unwrap() error { return false
return e.Err
} }
func IsUnauthorized(err error) bool { func KindFromRemoteError(err error) ErrorKind {
var e *ErrUnauthorized if rerr, ok := AsRemoteError(err); ok {
return errors.As(err, &e) return rerr.Kind
} }
type ErrInternal struct { return ErrInternal
Err error
}
// ErrInternal represent an internal error that should be returned to the user
func (e *ErrInternal) Error() string {
return e.Err.Error()
}
func NewErrInternal(err error) *ErrInternal {
return &ErrInternal{Err: err}
}
func (e *ErrInternal) Unwrap() error {
return e.Err
}
func IsInternal(err error) bool {
var e *ErrInternal
return errors.As(err, &e)
} }

124
internal/util/http.go Normal file
View File

@ -0,0 +1,124 @@
package util
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
errors "golang.org/x/xerrors"
)
func HTTPResponse(w http.ResponseWriter, code int, res interface{}) error {
w.Header().Set("Content-Type", "application/json")
if res != nil {
resj, err := json.Marshal(res)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return err
}
w.WriteHeader(code)
_, err = w.Write(resj)
return err
}
w.WriteHeader(code)
return nil
}
type ErrorResponse struct {
Code string `json:"code"`
Message string `json:"message"`
}
func ErrorResponseFromError(err error) *ErrorResponse {
if err == nil {
return nil
}
var derr *APIError
if errors.As(err, &derr) {
return &ErrorResponse{Code: string(derr.Code), Message: derr.Message}
}
// on generic error return an error response without any code
return &ErrorResponse{}
}
func HTTPError(w http.ResponseWriter, err error) bool {
if err == nil {
return false
}
response := ErrorResponseFromError(err)
resj, merr := json.Marshal(response)
if merr != nil {
w.WriteHeader(http.StatusInternalServerError)
return true
}
code := http.StatusInternalServerError
var derr *APIError
if errors.As(err, &derr) {
switch derr.Kind {
case ErrBadRequest:
code = http.StatusBadRequest
case ErrNotExist:
code = http.StatusNotFound
case ErrForbidden:
code = http.StatusForbidden
case ErrUnauthorized:
code = http.StatusUnauthorized
case ErrInternal:
code = http.StatusInternalServerError
}
}
w.WriteHeader(code)
_, _ = w.Write(resj)
return true
}
func ErrFromRemote(resp *http.Response) error {
if resp == nil {
return nil
}
if resp.StatusCode/100 == 2 {
return nil
}
response := &ErrorResponse{}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
// Re-populate error response body so it can be parsed by the caller if needed
resp.Body = ioutil.NopCloser(bytes.NewBuffer(data))
if err := json.Unmarshal(data, &response); err != nil {
return errors.Errorf("unknown api error (status: %d)", resp.StatusCode)
}
kind := ErrInternal
switch resp.StatusCode {
case http.StatusBadRequest:
kind = ErrBadRequest
case http.StatusNotFound:
kind = ErrNotExist
case http.StatusForbidden:
kind = ErrForbidden
case http.StatusUnauthorized:
kind = ErrUnauthorized
case http.StatusInternalServerError:
kind = ErrInternal
}
return NewRemoteError(kind, response.Code, response.Message)
}

View File

@ -20,17 +20,14 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"agola.io/agola/internal/util"
csapitypes "agola.io/agola/services/configstore/api/types" csapitypes "agola.io/agola/services/configstore/api/types"
"agola.io/agola/services/configstore/types"
cstypes "agola.io/agola/services/configstore/types" cstypes "agola.io/agola/services/configstore/types"
errors "golang.org/x/xerrors"
) )
var jsonContent = http.Header{"Content-Type": []string{"application/json"}} var jsonContent = http.Header{"Content-Type": []string{"application/json"}}
@ -78,20 +75,10 @@ func (c *Client) getResponse(ctx context.Context, method, path string, query url
return nil, err return nil, err
} }
if resp.StatusCode/100 != 2 { if err := util.ErrFromRemote(resp); err != nil {
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return resp, err return resp, err
} }
errMap := make(map[string]interface{})
if err = json.Unmarshal(data, &errMap); err != nil {
return resp, fmt.Errorf("unknown api error (code: %d): %s", resp.StatusCode, string(data))
}
return resp, errors.New(errMap["message"].(string))
}
return resp, nil return resp, nil
} }
@ -332,7 +319,7 @@ func (c *Client) DeleteProjectVariable(ctx context.Context, projectRef, variable
} }
func (c *Client) GetUser(ctx context.Context, userRef string) (*cstypes.User, *http.Response, error) { func (c *Client) GetUser(ctx context.Context, userRef string) (*cstypes.User, *http.Response, error) {
user := new(types.User) user := new(cstypes.User)
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/users/%s", userRef), nil, jsonContent, nil, user) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/users/%s", userRef), nil, jsonContent, nil, user)
return user, resp, err return user, resp, err
} }
@ -383,7 +370,7 @@ func (c *Client) CreateUser(ctx context.Context, req *csapitypes.CreateUserReque
return nil, nil, err return nil, nil, err
} }
user := new(types.User) user := new(cstypes.User)
resp, err := c.getParsedResponse(ctx, "POST", "/users", nil, jsonContent, bytes.NewReader(reqj), user) resp, err := c.getParsedResponse(ctx, "POST", "/users", nil, jsonContent, bytes.NewReader(reqj), user)
return user, resp, err return user, resp, err
} }
@ -394,7 +381,7 @@ func (c *Client) UpdateUser(ctx context.Context, userRef string, req *csapitypes
return nil, nil, err return nil, nil, err
} }
user := new(types.User) user := new(cstypes.User)
resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/users/%s", userRef), nil, jsonContent, bytes.NewReader(reqj), user) resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/users/%s", userRef), nil, jsonContent, bytes.NewReader(reqj), user)
return user, resp, err return user, resp, err
} }
@ -426,7 +413,7 @@ func (c *Client) CreateUserLA(ctx context.Context, userRef string, req *csapityp
return nil, nil, err return nil, nil, err
} }
la := new(types.LinkedAccount) la := new(cstypes.LinkedAccount)
resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/users/%s/linkedaccounts", userRef), nil, jsonContent, bytes.NewReader(reqj), la) resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/users/%s/linkedaccounts", userRef), nil, jsonContent, bytes.NewReader(reqj), la)
return la, resp, err return la, resp, err
} }
@ -441,7 +428,7 @@ func (c *Client) UpdateUserLA(ctx context.Context, userRef, laID string, req *cs
return nil, nil, err return nil, nil, err
} }
la := new(types.LinkedAccount) la := new(cstypes.LinkedAccount)
resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/users/%s/linkedaccounts/%s", userRef, laID), nil, jsonContent, bytes.NewReader(reqj), la) resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/users/%s/linkedaccounts/%s", userRef, laID), nil, jsonContent, bytes.NewReader(reqj), la)
return la, resp, err return la, resp, err
} }
@ -468,7 +455,7 @@ func (c *Client) GetUserOrgs(ctx context.Context, userRef string) ([]*csapitypes
} }
func (c *Client) GetRemoteSource(ctx context.Context, rsRef string) (*cstypes.RemoteSource, *http.Response, error) { func (c *Client) GetRemoteSource(ctx context.Context, rsRef string) (*cstypes.RemoteSource, *http.Response, error) {
rs := new(types.RemoteSource) rs := new(cstypes.RemoteSource)
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/remotesources/%s", rsRef), nil, jsonContent, nil, rs) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/remotesources/%s", rsRef), nil, jsonContent, nil, rs)
return rs, resp, err return rs, resp, err
} }
@ -490,24 +477,24 @@ func (c *Client) GetRemoteSources(ctx context.Context, start string, limit int,
return rss, resp, err return rss, resp, err
} }
func (c *Client) CreateRemoteSource(ctx context.Context, rs *cstypes.RemoteSource) (*types.RemoteSource, *http.Response, error) { func (c *Client) CreateRemoteSource(ctx context.Context, rs *cstypes.RemoteSource) (*cstypes.RemoteSource, *http.Response, error) {
rsj, err := json.Marshal(rs) rsj, err := json.Marshal(rs)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
rs = new(types.RemoteSource) rs = new(cstypes.RemoteSource)
resp, err := c.getParsedResponse(ctx, "POST", "/remotesources", nil, jsonContent, bytes.NewReader(rsj), rs) resp, err := c.getParsedResponse(ctx, "POST", "/remotesources", nil, jsonContent, bytes.NewReader(rsj), rs)
return rs, resp, err return rs, resp, err
} }
func (c *Client) UpdateRemoteSource(ctx context.Context, remoteSourceRef string, remoteSource *cstypes.RemoteSource) (*types.RemoteSource, *http.Response, error) { func (c *Client) UpdateRemoteSource(ctx context.Context, remoteSourceRef string, remoteSource *cstypes.RemoteSource) (*cstypes.RemoteSource, *http.Response, error) {
rsj, err := json.Marshal(remoteSource) rsj, err := json.Marshal(remoteSource)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
resRemoteSource := new(types.RemoteSource) resRemoteSource := new(cstypes.RemoteSource)
resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/remotesources/%s", url.PathEscape(remoteSourceRef)), nil, jsonContent, bytes.NewReader(rsj), resRemoteSource) resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/remotesources/%s", url.PathEscape(remoteSourceRef)), nil, jsonContent, bytes.NewReader(rsj), resRemoteSource)
return resRemoteSource, resp, err return resRemoteSource, resp, err
} }
@ -516,13 +503,13 @@ func (c *Client) DeleteRemoteSource(ctx context.Context, rsRef string) (*http.Re
return c.getResponse(ctx, "DELETE", fmt.Sprintf("/remotesources/%s", rsRef), nil, jsonContent, nil) return c.getResponse(ctx, "DELETE", fmt.Sprintf("/remotesources/%s", rsRef), nil, jsonContent, nil)
} }
func (c *Client) CreateOrg(ctx context.Context, org *cstypes.Organization) (*types.Organization, *http.Response, error) { func (c *Client) CreateOrg(ctx context.Context, org *cstypes.Organization) (*cstypes.Organization, *http.Response, error) {
oj, err := json.Marshal(org) oj, err := json.Marshal(org)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
org = new(types.Organization) org = new(cstypes.Organization)
resp, err := c.getParsedResponse(ctx, "POST", "/orgs", nil, jsonContent, bytes.NewReader(oj), org) resp, err := c.getParsedResponse(ctx, "POST", "/orgs", nil, jsonContent, bytes.NewReader(oj), org)
return org, resp, err return org, resp, err
} }
@ -540,7 +527,7 @@ func (c *Client) AddOrgMember(ctx context.Context, orgRef, userRef string, role
return nil, nil, err return nil, nil, err
} }
orgmember := new(types.OrganizationMember) orgmember := new(cstypes.OrganizationMember)
resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/orgs/%s/members/%s", orgRef, userRef), nil, jsonContent, bytes.NewReader(omj), orgmember) resp, err := c.getParsedResponse(ctx, "PUT", fmt.Sprintf("/orgs/%s/members/%s", orgRef, userRef), nil, jsonContent, bytes.NewReader(omj), orgmember)
return orgmember, resp, err return orgmember, resp, err
} }
@ -567,7 +554,7 @@ func (c *Client) GetOrgs(ctx context.Context, start string, limit int, asc bool)
} }
func (c *Client) GetOrg(ctx context.Context, orgRef string) (*cstypes.Organization, *http.Response, error) { func (c *Client) GetOrg(ctx context.Context, orgRef string) (*cstypes.Organization, *http.Response, error) {
org := new(types.Organization) org := new(cstypes.Organization)
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/orgs/%s", orgRef), nil, jsonContent, nil, org) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/orgs/%s", orgRef), nil, jsonContent, nil, org)
return org, resp, err return org, resp, err
} }

View File

@ -20,16 +20,14 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"strconv" "strconv"
"strings" "strings"
"agola.io/agola/internal/util"
gwapitypes "agola.io/agola/services/gateway/api/types" gwapitypes "agola.io/agola/services/gateway/api/types"
errors "golang.org/x/xerrors"
) )
var jsonContent = http.Header{"Content-Type": []string{"application/json"}} var jsonContent = http.Header{"Content-Type": []string{"application/json"}}
@ -80,20 +78,10 @@ func (c *Client) getResponse(ctx context.Context, method, path string, query url
return nil, err return nil, err
} }
if resp.StatusCode/100 != 2 { if err := util.ErrFromRemote(resp); err != nil {
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return resp, err return resp, err
} }
errMap := make(map[string]interface{})
if err = json.Unmarshal(data, &errMap); err != nil {
return resp, fmt.Errorf("unknown api error (code: %d): %s", resp.StatusCode, string(data))
}
return resp, errors.New(errMap["message"].(string))
}
return resp, nil return resp, nil
} }

View File

@ -20,15 +20,14 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"agola.io/agola/internal/util"
rsapitypes "agola.io/agola/services/runservice/api/types" rsapitypes "agola.io/agola/services/runservice/api/types"
rstypes "agola.io/agola/services/runservice/types" rstypes "agola.io/agola/services/runservice/types"
errors "golang.org/x/xerrors"
) )
var jsonContent = http.Header{"Content-Type": []string{"application/json"}} var jsonContent = http.Header{"Content-Type": []string{"application/json"}}
@ -80,20 +79,10 @@ func (c *Client) getResponse(ctx context.Context, method, path string, query url
return nil, err return nil, err
} }
if resp.StatusCode/100 != 2 { if err := util.ErrFromRemote(resp); err != nil {
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return resp, err return resp, err
} }
errMap := make(map[string]interface{})
if err = json.Unmarshal(data, &errMap); err != nil {
return resp, fmt.Errorf("unknown api error (code: %d): %s", resp.StatusCode, string(data))
}
return resp, errors.New(errMap["message"].(string))
}
return resp, nil return resp, nil
} }

View File

@ -1288,7 +1288,7 @@ func TestDirectRunLogs(t *testing.T) {
{ {
name: "test get log with unexisting step", name: "test get log with unexisting step",
step: 99, step: 99,
err: errors.Errorf("log doesn't exist"), err: util.NewRemoteError(util.ErrNotExist, "", ""),
}, },
{ {
name: "test delete log step 1", name: "test delete log step 1",
@ -1304,7 +1304,7 @@ func TestDirectRunLogs(t *testing.T) {
name: "test delete log with unexisting step", name: "test delete log with unexisting step",
step: 99, step: 99,
delete: true, delete: true,
err: errors.Errorf("log doesn't exist"), err: util.NewRemoteError(util.ErrNotExist, "", ""),
}, },
} }