*: Improve error handling

* Create an APIError that should only be used for api returned errors.
  It'll wrap an error and can have different Kinds and optional code and
  message.
* The http handlers will use the first APIError available in the
  error chain and generate a json response body containing the code and
  the user message. The wrapped error is internal and is not sent in the
  response.
  If no api error is available in the chain a generic internal
  server error will be returned.
* Add a RemoteError type that will be created from remote services calls
  (runservice, configstore). It's similar to the APIError but a
  different type to not propagate to the caller response and it'll not
  contain any wrapped error.
* Gateway: when we call a remote service, by default, we'll create a
  APIError using the RemoteError Kind (omitting the code and the
  message that usually must not be propagated).
  This is done for all the remote service calls as a starting point, in
  future, if this default behavior is not the right one for a specific
  remote service call, a new api error with a different kind and/or
  augmented with the calling service error codes and user messages could
  be created.
* datamanager: Use a dedicated ErrNotExist (and converting objectstorage
  ErrNotExist).
This commit is contained in:
Simone Gotti 2022-02-21 12:19:55 +01:00
parent b357cdc4ed
commit c1da3ab566
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 {
http.Error(w, "", http.StatusUnauthorized)
return
}
if err != nil { if err != nil {
if util.RemoteErrorIs(err, util.ErrNotExist) {
http.Error(w, "", http.StatusUnauthorized)
return
}
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"
}
return "unknown"
} }
func (e *ErrBadRequest) Error() string { type APIError struct {
return e.Err.Error() err error
Kind ErrorKind
Code ErrorCode
Message string
} }
func NewErrBadRequest(err error) *ErrBadRequest { func NewAPIError(kind ErrorKind, err error, options ...APIErrorOption) error {
return &ErrBadRequest{Err: err} derr := &APIError{err: err, Kind: kind}
for _, opt := range options {
opt(derr)
}
return derr
} }
func (e *ErrBadRequest) Unwrap() error { func (e *APIError) Error() string {
return e.Err return e.err.Error()
} }
func IsBadRequest(err error) bool { func (e *APIError) Unwrap() error {
var e *ErrBadRequest return e.err
return errors.As(err, &e)
} }
// ErrNotExist represent a not exist error type APIErrorOption func(e *APIError)
// it's used to differentiate an internal error from an user error
type ErrNotExist struct { func WithCode(code ErrorCode) APIErrorOption {
Err error return func(e *APIError) {
e.Code = code
}
} }
func (e *ErrNotExist) Error() string { func WithMessage(message string) APIErrorOption {
return e.Err.Error() return func(e *APIError) {
e.Message = message
}
} }
func NewErrNotExist(err error) *ErrNotExist { func AsAPIError(err error) (*APIError, bool) {
return &ErrNotExist{Err: err} var derr *APIError
return derr, errors.As(err, &derr)
} }
func (e *ErrNotExist) Unwrap() error { func APIErrorIs(err error, kind ErrorKind) bool {
return e.Err if derr, ok := AsAPIError(err); ok && derr.Kind == kind {
return true
}
return false
} }
func IsNotExist(err error) bool { // RemoteError is an error received from a remote call. It's similar to
var e *ErrNotExist // APIError but with another type so it can be distinguished and won't be
return errors.As(err, &e) // propagated to the api response.
type RemoteError struct {
Kind ErrorKind
Code string
Message string
} }
// ErrForbidden represent an error caused by an forbidden operation func NewRemoteError(kind ErrorKind, code string, message string) error {
// it's used to differentiate an internal error from an user error return &RemoteError{Kind: kind, Code: code, Message: message}
type ErrForbidden struct {
Err error
} }
func (e *ErrForbidden) Error() string { func (e *RemoteError) Error() string {
return e.Err.Error() code := e.Code
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)
}
return errStr
} }
func NewErrForbidden(err error) *ErrForbidden { func AsRemoteError(err error) (*RemoteError, bool) {
return &ErrForbidden{Err: err} var rerr *RemoteError
return rerr, errors.As(err, &rerr)
} }
func (e *ErrForbidden) Unwrap() error { func RemoteErrorIs(err error, kind ErrorKind) bool {
return e.Err if rerr, ok := AsRemoteError(err); ok && rerr.Kind == kind {
return true
}
return false
} }
func IsForbidden(err error) bool { func KindFromRemoteError(err error) ErrorKind {
var e *ErrForbidden if rerr, ok := AsRemoteError(err); ok {
return errors.As(err, &e) return rerr.Kind
} }
// ErrUnauthorized represent an error caused by an unauthorized request return ErrInternal
// it's used to differentiate an internal error from an user error
type ErrUnauthorized struct {
Err error
}
func (e *ErrUnauthorized) Error() string {
return e.Err.Error()
}
func NewErrUnauthorized(err error) *ErrUnauthorized {
return &ErrUnauthorized{Err: err}
}
func (e *ErrUnauthorized) Unwrap() error {
return e.Err
}
func IsUnauthorized(err error) bool {
var e *ErrUnauthorized
return errors.As(err, &e)
}
type ErrInternal struct {
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,18 +75,8 @@ 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() return resp, err
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
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,18 +78,8 @@ 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() return resp, err
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
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,18 +79,8 @@ 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() return resp, err
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
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, "", ""),
}, },
} }