*/api: Use helpers for error handling
* client: always parse the json error message field and return its contents * Use ErrBadRequest and ErrNotFound in every handler and command * Gateway: by default pass underlying service error (configstore, runservice) to client keeping the status code and message. In future, if some errors must be masked, we should change the specific parts that need special handling.
This commit is contained in:
parent
643dfe4072
commit
3642be6f21
|
@ -30,7 +30,10 @@ type ErrorResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrorResponseFromError(err error) *ErrorResponse {
|
func ErrorResponseFromError(err error) *ErrorResponse {
|
||||||
if util.IsErrBadRequest(err) {
|
switch {
|
||||||
|
case util.IsErrBadRequest(err):
|
||||||
|
fallthrough
|
||||||
|
case util.IsErrNotFound(err):
|
||||||
return &ErrorResponse{Message: err.Error()}
|
return &ErrorResponse{Message: err.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,26 +42,30 @@ func ErrorResponseFromError(err error) *ErrorResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
func httpError(w http.ResponseWriter, err error) bool {
|
func httpError(w http.ResponseWriter, err error) bool {
|
||||||
if err != nil {
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
response := ErrorResponseFromError(err)
|
response := ErrorResponseFromError(err)
|
||||||
resj, merr := json.Marshal(response)
|
resj, merr := json.Marshal(response)
|
||||||
if merr != nil {
|
if merr != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if util.IsErrBadRequest(err) {
|
switch {
|
||||||
|
case util.IsErrBadRequest(err):
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write(resj)
|
w.Write(resj)
|
||||||
} else {
|
case util.IsErrNotFound(err):
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
w.Write(resj)
|
||||||
|
default:
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write(resj)
|
w.Write(resj)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
|
|
@ -81,16 +81,14 @@ func (c *Client) getResponse(ctx context.Context, method, path string, query url
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) <= 1 {
|
errMap := make(map[string]interface{})
|
||||||
return resp, errors.New(resp.Status)
|
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))
|
||||||
// TODO(sgotti) use a json error response
|
|
||||||
|
|
||||||
return resp, errors.New(string(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
|
|
@ -19,10 +19,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sorintlab/agola/internal/db"
|
"github.com/sorintlab/agola/internal/db"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/command"
|
"github.com/sorintlab/agola/internal/services/configstore/command"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -54,7 +56,7 @@ func (h *OrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if org == nil {
|
if org == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("org %q doesn't exist", orgID)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +91,7 @@ func (h *OrgByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if org == nil {
|
if org == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("org %q doesn't exist", orgName)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +115,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,12 +178,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxOrgsLimit {
|
if limit > MaxOrgsLimit {
|
||||||
|
|
|
@ -19,11 +19,13 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sorintlab/agola/internal/db"
|
"github.com/sorintlab/agola/internal/db"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/command"
|
"github.com/sorintlab/agola/internal/services/configstore/command"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/common"
|
"github.com/sorintlab/agola/internal/services/configstore/common"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -42,13 +44,13 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
projectRefType, err := common.ParseRef(projectRef)
|
projectRefType, err := common.ParseRef(projectRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +72,7 @@ func (h *ProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if project == nil {
|
if project == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("project %q doesn't exist", projectRef)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +127,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sorintlab/agola/internal/db"
|
"github.com/sorintlab/agola/internal/db"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/command"
|
"github.com/sorintlab/agola/internal/services/configstore/command"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -41,7 +43,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ func (h *ProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
if projectGroup == nil {
|
if projectGroup == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("project group %q doesn't exist", projectGroupRef)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +82,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ func (h *ProjectGroupProjectsHandler) ServeHTTP(w http.ResponseWriter, r *http.R
|
||||||
}
|
}
|
||||||
|
|
||||||
if projectGroup == nil {
|
if projectGroup == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("project group %q doesn't exist", projectGroupRef)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +132,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +148,7 @@ func (h *ProjectGroupSubgroupsHandler) ServeHTTP(w http.ResponseWriter, r *http.
|
||||||
}
|
}
|
||||||
|
|
||||||
if projectGroup == nil {
|
if projectGroup == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("project group %q doesn't exist", projectGroupRef)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +185,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sorintlab/agola/internal/db"
|
"github.com/sorintlab/agola/internal/db"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/command"
|
"github.com/sorintlab/agola/internal/services/configstore/command"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -54,7 +56,7 @@ func (h *RemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
if remoteSource == nil {
|
if remoteSource == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("remote source %q doesn't exist", remoteSourceID)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +91,7 @@ func (h *RemoteSourceByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
|
||||||
}
|
}
|
||||||
|
|
||||||
if remoteSource == nil {
|
if remoteSource == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("remote source %q doesn't exist", remoteSourceName)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +116,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,12 +178,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxRemoteSourcesLimit {
|
if limit > MaxRemoteSourcesLimit {
|
||||||
|
|
|
@ -18,10 +18,12 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sorintlab/agola/internal/db"
|
"github.com/sorintlab/agola/internal/db"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/command"
|
"github.com/sorintlab/agola/internal/services/configstore/command"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -53,7 +55,7 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if secret == nil {
|
if secret == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("secret %q doesn't exist", secretID)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +137,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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sorintlab/agola/internal/db"
|
"github.com/sorintlab/agola/internal/db"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/command"
|
"github.com/sorintlab/agola/internal/services/configstore/command"
|
||||||
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
"github.com/sorintlab/agola/internal/services/configstore/readdb"
|
||||||
|
@ -55,7 +56,7 @@ func (h *UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("user %q doesn't exist", userID)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ func (h *UserByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("user %q doesn't exist", userName)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var req *CreateUserRequest
|
var req *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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,12 +197,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxUsersLimit {
|
if limit > MaxUsersLimit {
|
||||||
|
@ -235,7 +236,7 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user == nil {
|
if user == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("user with required token doesn't exist")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
users = []*types.User{user}
|
users = []*types.User{user}
|
||||||
|
@ -254,7 +255,7 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user == nil {
|
if user == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("user with linked account %q token doesn't exist", linkedAccountID)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
users = []*types.User{user}
|
users = []*types.User{user}
|
||||||
|
@ -274,7 +275,7 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if user == nil {
|
if user == nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(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}
|
||||||
|
@ -323,7 +324,7 @@ func (h *CreateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
var req CreateUserLARequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +398,7 @@ func (h *UpdateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
var req UpdateUserLARequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +447,7 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
||||||
var req CreateUserTokenRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ func TestUser(t *testing.T) {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
t.Run("create duplicated user", func(t *testing.T) {
|
t.Run("create duplicated user", func(t *testing.T) {
|
||||||
expectedErr := fmt.Sprintf("bad request: user with name %q already exists", "user01")
|
expectedErr := fmt.Sprintf("user with name %q already exists", "user01")
|
||||||
_, err := cs.ch.CreateUser(ctx, &command.CreateUserRequest{UserName: "user01"})
|
_, err := cs.ch.CreateUser(ctx, &command.CreateUserRequest{UserName: "user01"})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected error %v, got nil err", expectedErr)
|
t.Fatalf("expected error %v, got nil err", expectedErr)
|
||||||
|
@ -432,7 +432,7 @@ func TestProjectGroupsAndProjects(t *testing.T) {
|
||||||
|
|
||||||
t.Run("create duplicated project in user root project group", func(t *testing.T) {
|
t.Run("create duplicated project in user root project group", func(t *testing.T) {
|
||||||
projectName := "project01"
|
projectName := "project01"
|
||||||
expectedErr := fmt.Sprintf("bad request: project with name %q, path %q already exists", projectName, path.Join("user", user.UserName, projectName))
|
expectedErr := fmt.Sprintf("project with name %q, path %q already exists", projectName, path.Join("user", user.UserName, projectName))
|
||||||
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("user", user.UserName)}})
|
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("user", user.UserName)}})
|
||||||
if err.Error() != expectedErr {
|
if err.Error() != expectedErr {
|
||||||
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
||||||
|
@ -440,7 +440,7 @@ func TestProjectGroupsAndProjects(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("create duplicated project in org root project group", func(t *testing.T) {
|
t.Run("create duplicated project in org root project group", func(t *testing.T) {
|
||||||
projectName := "project01"
|
projectName := "project01"
|
||||||
expectedErr := fmt.Sprintf("bad request: project with name %q, path %q already exists", projectName, path.Join("org", org.Name, projectName))
|
expectedErr := fmt.Sprintf("project with name %q, path %q already exists", projectName, path.Join("org", org.Name, projectName))
|
||||||
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("org", org.Name)}})
|
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("org", org.Name)}})
|
||||||
if err.Error() != expectedErr {
|
if err.Error() != expectedErr {
|
||||||
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
||||||
|
@ -449,7 +449,7 @@ func TestProjectGroupsAndProjects(t *testing.T) {
|
||||||
|
|
||||||
t.Run("create duplicated project in user non root project group", func(t *testing.T) {
|
t.Run("create duplicated project in user non root project group", func(t *testing.T) {
|
||||||
projectName := "project01"
|
projectName := "project01"
|
||||||
expectedErr := fmt.Sprintf("bad request: project with name %q, path %q already exists", projectName, path.Join("user", user.UserName, "projectgroup01", projectName))
|
expectedErr := fmt.Sprintf("project with name %q, path %q already exists", projectName, path.Join("user", user.UserName, "projectgroup01", projectName))
|
||||||
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("user", user.UserName, "projectgroup01")}})
|
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("user", user.UserName, "projectgroup01")}})
|
||||||
if err.Error() != expectedErr {
|
if err.Error() != expectedErr {
|
||||||
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
||||||
|
@ -457,7 +457,7 @@ func TestProjectGroupsAndProjects(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("create duplicated project in org non root project group", func(t *testing.T) {
|
t.Run("create duplicated project in org non root project group", func(t *testing.T) {
|
||||||
projectName := "project01"
|
projectName := "project01"
|
||||||
expectedErr := fmt.Sprintf("bad request: project with name %q, path %q already exists", projectName, path.Join("org", org.Name, "projectgroup01", projectName))
|
expectedErr := fmt.Sprintf("project with name %q, path %q already exists", projectName, path.Join("org", org.Name, "projectgroup01", projectName))
|
||||||
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("org", org.Name, "projectgroup01")}})
|
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: projectName, Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: path.Join("org", org.Name, "projectgroup01")}})
|
||||||
if err.Error() != expectedErr {
|
if err.Error() != expectedErr {
|
||||||
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
||||||
|
@ -465,14 +465,14 @@ func TestProjectGroupsAndProjects(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("create project in unexistent project group", func(t *testing.T) {
|
t.Run("create project in unexistent project group", func(t *testing.T) {
|
||||||
expectedErr := `bad request: project group with id "unexistentid" doesn't exist`
|
expectedErr := `project group with id "unexistentid" doesn't exist`
|
||||||
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: "project01", Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: "unexistentid"}})
|
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: "project01", Parent: types.Parent{Type: types.ConfigTypeProjectGroup, ID: "unexistentid"}})
|
||||||
if err.Error() != expectedErr {
|
if err.Error() != expectedErr {
|
||||||
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("create project without parent id specified", func(t *testing.T) {
|
t.Run("create project without parent id specified", func(t *testing.T) {
|
||||||
expectedErr := "bad request: project parent id required"
|
expectedErr := "project parent id required"
|
||||||
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: "project01"})
|
_, err := cs.ch.CreateProject(ctx, &types.Project{Name: "project01"})
|
||||||
if err.Error() != expectedErr {
|
if err.Error() != expectedErr {
|
||||||
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
t.Fatalf("expected err %v, got err: %v", expectedErr, err)
|
||||||
|
|
|
@ -30,7 +30,10 @@ type ErrorResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrorResponseFromError(err error) *ErrorResponse {
|
func ErrorResponseFromError(err error) *ErrorResponse {
|
||||||
if util.IsErrBadRequest(err) {
|
switch {
|
||||||
|
case util.IsErrBadRequest(err):
|
||||||
|
fallthrough
|
||||||
|
case util.IsErrNotFound(err):
|
||||||
return &ErrorResponse{Message: err.Error()}
|
return &ErrorResponse{Message: err.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,26 +42,30 @@ func ErrorResponseFromError(err error) *ErrorResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
func httpError(w http.ResponseWriter, err error) bool {
|
func httpError(w http.ResponseWriter, err error) bool {
|
||||||
if err != nil {
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
response := ErrorResponseFromError(err)
|
response := ErrorResponseFromError(err)
|
||||||
resj, merr := json.Marshal(response)
|
resj, merr := json.Marshal(response)
|
||||||
if merr != nil {
|
if merr != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if util.IsErrBadRequest(err) {
|
switch {
|
||||||
|
case util.IsErrBadRequest(err):
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write(resj)
|
w.Write(resj)
|
||||||
} else {
|
case util.IsErrNotFound(err):
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
w.Write(resj)
|
||||||
|
default:
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write(resj)
|
w.Write(resj)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
@ -77,6 +84,29 @@ func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
||||||
return nil
|
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) (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"])
|
||||||
|
|
|
@ -84,16 +84,14 @@ func (c *Client) getResponse(ctx context.Context, method, path string, query url
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) <= 1 {
|
errMap := make(map[string]interface{})
|
||||||
return resp, errors.New(resp.Status)
|
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))
|
||||||
// TODO(sgotti) use a json error response
|
|
||||||
|
|
||||||
return resp, errors.New(string(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
|
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/command"
|
"github.com/sorintlab/agola/internal/services/gateway/command"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -47,7 +48,7 @@ func (h *OAuth2CallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
|
||||||
cresp, err := h.ch.HandleOauth2Callback(ctx, code, state)
|
cresp, err := h.ch.HandleOauth2Callback(ctx, code, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/command"
|
"github.com/sorintlab/agola/internal/services/gateway/command"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -46,7 +48,7 @@ func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var req CreateOrgRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,13 +83,8 @@ func (h *DeleteOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
orgName := vars["orgname"]
|
orgName := vars["orgname"]
|
||||||
|
|
||||||
resp, err := h.configstoreClient.DeleteOrg(ctx, orgName)
|
resp, err := h.configstoreClient.DeleteOrg(ctx, orgName)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,13 +108,8 @@ func (h *OrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
orgID := vars["orgid"]
|
orgID := vars["orgid"]
|
||||||
|
|
||||||
org, resp, err := h.configstoreClient.GetOrg(ctx, orgID)
|
org, resp, err := h.configstoreClient.GetOrg(ctx, orgID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,13 +134,8 @@ func (h *OrgByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
orgName := vars["orgname"]
|
orgName := vars["orgname"]
|
||||||
|
|
||||||
org, resp, err := h.configstoreClient.GetOrgByName(ctx, orgName)
|
org, resp, err := h.configstoreClient.GetOrgByName(ctx, orgName)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,12 +178,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxRunsLimit {
|
if limit > MaxRunsLimit {
|
||||||
|
@ -210,13 +197,8 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
start := query.Get("start")
|
start := query.Get("start")
|
||||||
|
|
||||||
csorgs, resp, err := h.configstoreClient.GetOrgs(ctx, start, limit, asc)
|
csorgs, resp, err := h.configstoreClient.GetOrgs(ctx, start, limit, asc)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,14 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/command"
|
"github.com/sorintlab/agola/internal/services/gateway/command"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -53,16 +54,16 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
var req CreateProjectRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxUserID := ctx.Value("userid")
|
userIDVal := ctx.Value("userid")
|
||||||
if ctxUserID == nil {
|
if userIDVal == nil {
|
||||||
http.Error(w, "no authenticated user", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userID := ctxUserID.(string)
|
userID := userIDVal.(string)
|
||||||
h.log.Infof("userID: %q", userID)
|
h.log.Infof("userID: %q", userID)
|
||||||
|
|
||||||
creq := &command.CreateProjectRequest{
|
creq := &command.CreateProjectRequest{
|
||||||
|
@ -102,7 +103,7 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,29 +130,19 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
project, resp, err := h.configstoreClient.GetProject(ctx, projectRef)
|
project, resp, err := h.configstoreClient.GetProject(ctx, projectRef)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, fmt.Sprintf("project with ref %q doesn't exist", projectRef), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err = h.configstoreClient.DeleteProject(ctx, project.ID)
|
resp, err = h.configstoreClient.DeleteProject(ctx, project.ID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,18 +165,13 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
project, resp, err := h.configstoreClient.GetProject(ctx, projectRef)
|
project, resp, err := h.configstoreClient.GetProject(ctx, projectRef)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,11 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/command"
|
"github.com/sorintlab/agola/internal/services/gateway/command"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -49,16 +51,16 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
|
||||||
var req CreateProjectGroupRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxUserID := ctx.Value("userid")
|
userIDVal := ctx.Value("userid")
|
||||||
if ctxUserID == nil {
|
if userIDVal == nil {
|
||||||
http.Error(w, "no authenticated user", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userID := ctxUserID.(string)
|
userID := userIDVal.(string)
|
||||||
h.log.Infof("userID: %q", userID)
|
h.log.Infof("userID: %q", userID)
|
||||||
|
|
||||||
creq := &command.CreateProjectGroupRequest{
|
creq := &command.CreateProjectGroupRequest{
|
||||||
|
@ -68,9 +70,8 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
|
||||||
}
|
}
|
||||||
|
|
||||||
projectGroup, err := h.ch.CreateProjectGroup(ctx, creq)
|
projectGroup, err := h.ch.CreateProjectGroup(ctx, creq)
|
||||||
if err != nil {
|
if httpError(w, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,18 +95,13 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
projectGroup, resp, err := h.configstoreClient.GetProjectGroup(ctx, projectGroupRef)
|
projectGroup, resp, err := h.configstoreClient.GetProjectGroup(ctx, projectGroupRef)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,18 +125,13 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
csprojects, resp, err := h.configstoreClient.GetProjectGroupProjects(ctx, projectGroupRef)
|
csprojects, resp, err := h.configstoreClient.GetProjectGroupProjects(ctx, projectGroupRef)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,18 +159,13 @@ 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cssubgroups, resp, err := h.configstoreClient.GetProjectGroupSubgroups(ctx, projectGroupRef)
|
cssubgroups, resp, err := h.configstoreClient.GetProjectGroupSubgroups(ctx, projectGroupRef)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,19 +15,18 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/common"
|
"github.com/sorintlab/agola/internal/services/gateway/command"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
"github.com/sorintlab/agola/internal/util"
|
"github.com/sorintlab/agola/internal/util"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateRemoteSourceRequest struct {
|
type CreateRemoteSourceRequest struct {
|
||||||
|
@ -41,11 +40,11 @@ type CreateRemoteSourceRequest struct {
|
||||||
|
|
||||||
type CreateRemoteSourceHandler struct {
|
type CreateRemoteSourceHandler struct {
|
||||||
log *zap.SugaredLogger
|
log *zap.SugaredLogger
|
||||||
configstoreClient *csapi.Client
|
ch *command.CommandHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCreateRemoteSourceHandler(logger *zap.Logger, configstoreClient *csapi.Client) *CreateRemoteSourceHandler {
|
func NewCreateRemoteSourceHandler(logger *zap.Logger, ch *command.CommandHandler) *CreateRemoteSourceHandler {
|
||||||
return &CreateRemoteSourceHandler{log: logger.Sugar(), configstoreClient: configstoreClient}
|
return &CreateRemoteSourceHandler{log: logger.Sugar(), ch: ch}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -54,13 +53,21 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
|
||||||
var req CreateRemoteSourceRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rs, err := h.createRemoteSource(ctx, &req)
|
creq := &command.CreateRemoteSourceRequest{
|
||||||
if err != nil {
|
Name: req.Name,
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
APIURL: req.APIURL,
|
||||||
|
Type: req.Type,
|
||||||
|
AuthType: req.AuthType,
|
||||||
|
Oauth2ClientID: req.Oauth2ClientID,
|
||||||
|
Oauth2ClientSecret: req.Oauth2ClientSecret,
|
||||||
|
}
|
||||||
|
rs, err := h.ch.CreateRemoteSource(ctx, creq)
|
||||||
|
if httpError(w, err) {
|
||||||
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,57 +77,6 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CreateRemoteSourceHandler) createRemoteSource(ctx context.Context, req *CreateRemoteSourceRequest) (*types.RemoteSource, error) {
|
|
||||||
if !util.ValidateName(req.Name) {
|
|
||||||
return nil, errors.Errorf("invalid remotesource name %q", req.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Name == "" {
|
|
||||||
return nil, errors.Errorf("remotesource name required")
|
|
||||||
}
|
|
||||||
if req.APIURL == "" {
|
|
||||||
return nil, errors.Errorf("remotesource api url required")
|
|
||||||
}
|
|
||||||
if req.Type == "" {
|
|
||||||
return nil, errors.Errorf("remotesource type required")
|
|
||||||
}
|
|
||||||
if req.AuthType == "" {
|
|
||||||
return nil, errors.Errorf("remotesource auth type required")
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate if the remote source type supports the required auth type
|
|
||||||
if !common.SourceSupportsAuthType(types.RemoteSourceType(req.Type), types.RemoteSourceAuthType(req.AuthType)) {
|
|
||||||
return nil, errors.Errorf("remotesource type %q doesn't support auth type %q", req.Type, req.AuthType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.AuthType == string(types.RemoteSourceAuthTypeOauth2) {
|
|
||||||
if req.Oauth2ClientID == "" {
|
|
||||||
return nil, errors.Errorf("remotesource oauth2 clientid required")
|
|
||||||
}
|
|
||||||
if req.Oauth2ClientSecret == "" {
|
|
||||||
return nil, errors.Errorf("remotesource oauth2 client secret required")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rs := &types.RemoteSource{
|
|
||||||
Name: req.Name,
|
|
||||||
Type: types.RemoteSourceType(req.Type),
|
|
||||||
AuthType: types.RemoteSourceAuthType(req.AuthType),
|
|
||||||
APIURL: req.APIURL,
|
|
||||||
Oauth2ClientID: req.Oauth2ClientID,
|
|
||||||
Oauth2ClientSecret: req.Oauth2ClientSecret,
|
|
||||||
}
|
|
||||||
|
|
||||||
h.log.Infof("creating remotesource")
|
|
||||||
rs, _, err := h.configstoreClient.CreateRemoteSource(ctx, rs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to create remotesource")
|
|
||||||
}
|
|
||||||
h.log.Infof("remotesource %s created, ID: %s", rs.Name, rs.ID)
|
|
||||||
|
|
||||||
return rs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type RemoteSourceResponse struct {
|
type RemoteSourceResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
@ -151,13 +107,8 @@ func (h *RemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
rsID := vars["id"]
|
rsID := vars["id"]
|
||||||
|
|
||||||
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, rsID)
|
rs, resp, err := h.configstoreClient.GetRemoteSource(ctx, rsID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,12 +138,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxRunsLimit {
|
if limit > MaxRunsLimit {
|
||||||
|
@ -206,13 +157,8 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
start := query.Get("start")
|
start := query.Get("start")
|
||||||
|
|
||||||
csRemoteSources, resp, err := h.configstoreClient.GetRemoteSources(ctx, start, limit, asc)
|
csRemoteSources, resp, err := h.configstoreClient.GetRemoteSources(ctx, start, limit, asc)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,8 @@ func (h *ReposHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
req, err := http.NewRequest(r.Method, u.String(), r.Body)
|
req, err := http.NewRequest(r.Method, u.String(), r.Body)
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
h.log.Errorf("err: %+v", err)
|
||||||
|
httpError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
rsapi "github.com/sorintlab/agola/internal/services/runservice/scheduler/api"
|
rsapi "github.com/sorintlab/agola/internal/services/runservice/scheduler/api"
|
||||||
rstypes "github.com/sorintlab/agola/internal/services/runservice/types"
|
rstypes "github.com/sorintlab/agola/internal/services/runservice/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -219,13 +221,8 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
runID := vars["runid"]
|
runID := vars["runid"]
|
||||||
|
|
||||||
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID)
|
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,13 +248,8 @@ func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
taskID := vars["taskid"]
|
taskID := vars["taskid"]
|
||||||
|
|
||||||
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID)
|
runResp, resp, err := h.runserviceClient.GetRun(ctx, runID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +258,7 @@ func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
rt, ok := run.RunTasks[taskID]
|
rt, ok := run.RunTasks[taskID]
|
||||||
if !ok {
|
if !ok {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
httpError(w, util.NewErrNotFound(errors.Errorf("run %q task %q not found", runID, taskID)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rct := rc.Tasks[rt.ID]
|
rct := rc.Tasks[rt.ID]
|
||||||
|
@ -318,7 +310,7 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
groups := q["group"]
|
groups := q["group"]
|
||||||
// we require that groups are specified to not return all runs
|
// we require that groups are specified to not return all runs
|
||||||
if len(groups) == 0 {
|
if len(groups) == 0 {
|
||||||
http.Error(w, "not groups specified", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("no groups specified")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,12 +324,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxRunsLimit {
|
if limit > MaxRunsLimit {
|
||||||
|
@ -351,13 +343,8 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
start := q.Get("start")
|
start := q.Get("start")
|
||||||
|
|
||||||
runsResp, resp, err := h.runserviceClient.GetRuns(ctx, phaseFilter, groups, lastRun, changeGroups, start, limit, asc)
|
runsResp, resp, err := h.runserviceClient.GetRuns(ctx, phaseFilter, groups, lastRun, changeGroups, start, limit, asc)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +388,7 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var req RunActionsRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,13 +400,8 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := h.runserviceClient.CreateRun(ctx, rsreq)
|
resp, err := h.runserviceClient.CreateRun(ctx, rsreq)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,13 +411,8 @@ func (h *RunActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := h.runserviceClient.RunActions(ctx, runID, rsreq)
|
resp, err := h.runserviceClient.RunActions(ctx, runID, rsreq)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +447,7 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
|
||||||
var req RunTaskActionsRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,17 +459,13 @@ func (h *RunTaskActionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := h.runserviceClient.RunTaskActions(ctx, runID, taskID, rsreq)
|
resp, err := h.runserviceClient.RunTaskActions(ctx, runID, taskID, rsreq)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("wrong action type %q", req.ActionType)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,23 +486,23 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
runID := q.Get("runID")
|
runID := q.Get("runID")
|
||||||
if runID == "" {
|
if runID == "" {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("empty run id")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
taskID := q.Get("taskID")
|
taskID := q.Get("taskID")
|
||||||
if taskID == "" {
|
if taskID == "" {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(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 == "" {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("no setup or step number provided")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if setup && stepStr != "" {
|
if setup && stepStr != "" {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("both setup and step number provided")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +511,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse step number")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,13 +529,8 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := h.runserviceClient.GetLogs(ctx, runID, taskID, setup, step, follow, stream)
|
resp, err := h.runserviceClient.GetLogs(ctx, runID, taskID, setup, step, follow, stream)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,14 +62,15 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var cssecrets []*types.Secret
|
var cssecrets []*types.Secret
|
||||||
|
var resp *http.Response
|
||||||
switch parentType {
|
switch parentType {
|
||||||
case types.ConfigTypeProjectGroup:
|
case types.ConfigTypeProjectGroup:
|
||||||
cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, parentRef, tree)
|
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, parentRef, tree)
|
||||||
case types.ConfigTypeProject:
|
case types.ConfigTypeProject:
|
||||||
cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, parentRef, tree)
|
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, parentRef, tree)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,14 +116,13 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
var req CreateSecretRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !util.ValidateName(req.Name) {
|
if !util.ValidateName(req.Name) {
|
||||||
err := errors.Errorf("invalid secret name %q", req.Name)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("invalid secret name %q", req.Name)))
|
||||||
h.log.Errorf("err: %+v", err)
|
return
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &types.Secret{
|
s := &types.Secret{
|
||||||
|
@ -131,16 +131,17 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
Data: req.Data,
|
Data: req.Data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var resp *http.Response
|
||||||
switch parentType {
|
switch parentType {
|
||||||
case types.ConfigTypeProjectGroup:
|
case types.ConfigTypeProjectGroup:
|
||||||
h.log.Infof("creating project group secret")
|
h.log.Infof("creating project group secret")
|
||||||
s, _, err = h.configstoreClient.CreateProjectGroupSecret(ctx, parentRef, s)
|
s, resp, err = h.configstoreClient.CreateProjectGroupSecret(ctx, parentRef, s)
|
||||||
case types.ConfigTypeProject:
|
case types.ConfigTypeProject:
|
||||||
h.log.Infof("creating project secret")
|
h.log.Infof("creating project secret")
|
||||||
s, _, err = h.configstoreClient.CreateProjectSecret(ctx, parentRef, s)
|
s, resp, err = h.configstoreClient.CreateProjectSecret(ctx, parentRef, s)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.log.Infof("secret %s created, ID: %s", s.Name, s.ID)
|
h.log.Infof("secret %s created, ID: %s", s.Name, s.ID)
|
||||||
|
@ -179,15 +180,11 @@ func (h *DeleteSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
h.log.Infof("deleting project secret")
|
h.log.Infof("deleting project secret")
|
||||||
resp, err = h.configstoreClient.DeleteProjectSecret(ctx, parentRef, secretName)
|
resp, err = h.configstoreClient.DeleteProjectSecret(ctx, parentRef, secretName)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
|
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,12 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
gitsource "github.com/sorintlab/agola/internal/gitsources"
|
gitsource "github.com/sorintlab/agola/internal/gitsources"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/command"
|
"github.com/sorintlab/agola/internal/services/gateway/command"
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -49,7 +51,7 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var req CreateUserRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,14 +86,13 @@ func (h *DeleteUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
userName := vars["username"]
|
userName := vars["username"]
|
||||||
|
|
||||||
resp, err := h.configstoreClient.DeleteUser(ctx, userName)
|
resp, err := h.configstoreClient.DeleteUser(ctx, userName)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,19 +110,14 @@ func (h *CurrentUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
userIDVal := ctx.Value("userid")
|
userIDVal := ctx.Value("userid")
|
||||||
if userIDVal == nil {
|
if userIDVal == nil {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("user not authenticated")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userID := userIDVal.(string)
|
userID := userIDVal.(string)
|
||||||
|
|
||||||
user, resp, err := h.configstoreClient.GetUser(ctx, userID)
|
user, resp, err := h.configstoreClient.GetUser(ctx, userID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,13 +142,8 @@ func (h *UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
userID := vars["userid"]
|
userID := vars["userid"]
|
||||||
|
|
||||||
user, resp, err := h.configstoreClient.GetUser(ctx, userID)
|
user, resp, err := h.configstoreClient.GetUser(ctx, userID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,13 +168,8 @@ func (h *UserByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
userName := vars["username"]
|
userName := vars["username"]
|
||||||
|
|
||||||
user, resp, err := h.configstoreClient.GetUserByName(ctx, userName)
|
user, resp, err := h.configstoreClient.GetUserByName(ctx, userName)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,12 +219,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 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Wrapf(err, "cannot parse limit")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
http.Error(w, "limit must be greater or equal than 0", http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("limit must be greater or equal than 0")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if limit > MaxRunsLimit {
|
if limit > MaxRunsLimit {
|
||||||
|
@ -252,13 +238,8 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
start := query.Get("start")
|
start := query.Get("start")
|
||||||
|
|
||||||
csusers, resp, err := h.configstoreClient.GetUsers(ctx, start, limit, asc)
|
csusers, resp, err := h.configstoreClient.GetUsers(ctx, start, limit, asc)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,14 +281,13 @@ func (h *CreateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
var req *CreateUserLARequest
|
var req *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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.createUserLA(ctx, userName, req)
|
res, err := h.createUserLA(ctx, userName, req)
|
||||||
if err != nil {
|
if httpError(w, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,10 +336,9 @@ func (h *DeleteUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
userName := vars["username"]
|
userName := vars["username"]
|
||||||
laID := vars["laid"]
|
laID := vars["laid"]
|
||||||
|
|
||||||
_, err := h.configstoreClient.DeleteUserLA(ctx, userName, laID)
|
resp, err := h.configstoreClient.DeleteUserLA(ctx, userName, laID)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +372,7 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
||||||
var req CreateUserTokenRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,10 +412,9 @@ func (h *DeleteUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
||||||
tokenName := vars["tokenname"]
|
tokenName := vars["tokenname"]
|
||||||
|
|
||||||
h.log.Infof("deleting user %q token %q", userName, tokenName)
|
h.log.Infof("deleting user %q token %q", userName, tokenName)
|
||||||
_, err := h.configstoreClient.DeleteUserToken(ctx, userName, tokenName)
|
resp, err := h.configstoreClient.DeleteUserToken(ctx, userName, tokenName)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,14 +447,13 @@ func (h *RegisterUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
var req *RegisterUserRequest
|
var req *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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.registerUser(ctx, req)
|
res, err := h.registerUser(ctx, req)
|
||||||
if err != nil {
|
if httpError(w, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,14 +504,13 @@ func (h *AuthorizeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var req *LoginUserRequest
|
var req *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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.authorize(ctx, req)
|
res, err := h.authorize(ctx, req)
|
||||||
if err != nil {
|
if httpError(w, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,14 +569,13 @@ func (h *LoginUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
var req *LoginUserRequest
|
var req *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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.loginUser(ctx, req)
|
res, err := h.loginUser(ctx, req)
|
||||||
if err != nil {
|
if httpError(w, err) {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,33 +94,31 @@ func (h *VariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
switch parentType {
|
switch parentType {
|
||||||
case types.ConfigTypeProjectGroup:
|
case types.ConfigTypeProjectGroup:
|
||||||
var err error
|
var err error
|
||||||
csvars, _, err = h.configstoreClient.GetProjectGroupVariables(ctx, parentRef, tree)
|
var resp *http.Response
|
||||||
if err != nil {
|
csvars, resp, err = h.configstoreClient.GetProjectGroupVariables(ctx, parentRef, tree)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, parentRef, true)
|
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, parentRef, true)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case types.ConfigTypeProject:
|
case types.ConfigTypeProject:
|
||||||
var err error
|
var err error
|
||||||
csvars, _, err = h.configstoreClient.GetProjectVariables(ctx, parentRef, tree)
|
var resp *http.Response
|
||||||
if err != nil {
|
csvars, resp, err = h.configstoreClient.GetProjectVariables(ctx, parentRef, tree)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, parentRef, true)
|
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, parentRef, true)
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if removeoverriden {
|
if removeoverriden {
|
||||||
// remove overriden variables
|
// remove overriden variables
|
||||||
|
@ -163,20 +161,18 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
|
||||||
var req CreateVariableRequest
|
var req 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 {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
httpError(w, util.NewErrBadRequest(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !util.ValidateName(req.Name) {
|
if !util.ValidateName(req.Name) {
|
||||||
err := errors.Errorf("invalid variable name %q", req.Name)
|
httpError(w, util.NewErrBadRequest(errors.Errorf("invalid secret name %q", req.Name)))
|
||||||
h.log.Errorf("err: %+v", err)
|
return
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.Values) == 0 {
|
if len(req.Values) == 0 {
|
||||||
err := errors.Errorf("empty variable values")
|
httpError(w, util.NewErrBadRequest(errors.Errorf("empty variable values")))
|
||||||
h.log.Errorf("err: %+v", err)
|
return
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v := &types.Variable{
|
v := &types.Variable{
|
||||||
|
@ -193,26 +189,35 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
|
||||||
switch parentType {
|
switch parentType {
|
||||||
case types.ConfigTypeProjectGroup:
|
case types.ConfigTypeProjectGroup:
|
||||||
var err error
|
var err error
|
||||||
cssecrets, _, err = h.configstoreClient.GetProjectGroupSecrets(ctx, parentRef, true)
|
var resp *http.Response
|
||||||
if err != nil {
|
cssecrets, resp, err = h.configstoreClient.GetProjectGroupSecrets(ctx, parentRef, true)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h.log.Infof("creating project group variable")
|
h.log.Infof("creating project group variable")
|
||||||
v, _, err = h.configstoreClient.CreateProjectGroupVariable(ctx, parentRef, v)
|
v, resp, err = h.configstoreClient.CreateProjectGroupVariable(ctx, parentRef, v)
|
||||||
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
|
h.log.Errorf("err: %+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
case types.ConfigTypeProject:
|
case types.ConfigTypeProject:
|
||||||
cssecrets, _, err = h.configstoreClient.GetProjectSecrets(ctx, parentRef, true)
|
var err error
|
||||||
if err != nil {
|
var resp *http.Response
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
cssecrets, resp, err = h.configstoreClient.GetProjectSecrets(ctx, parentRef, true)
|
||||||
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
|
h.log.Errorf("err: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h.log.Infof("creating project variable")
|
h.log.Infof("creating project variable")
|
||||||
v, _, err = h.configstoreClient.CreateProjectVariable(ctx, parentRef, v)
|
v, resp, err = h.configstoreClient.CreateProjectVariable(ctx, parentRef, v)
|
||||||
}
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if err != nil {
|
h.log.Errorf("err: %+v", err)
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
h.log.Infof("variable %s created, ID: %s", v.Name, v.ID)
|
h.log.Infof("variable %s created, ID: %s", v.Name, v.ID)
|
||||||
|
|
||||||
res := createVariableResponse(v, cssecrets)
|
res := createVariableResponse(v, cssecrets)
|
||||||
|
@ -250,15 +255,11 @@ func (h *DeleteVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
|
||||||
h.log.Infof("deleting project variable")
|
h.log.Infof("deleting project variable")
|
||||||
resp, err = h.configstoreClient.DeleteProjectVariable(ctx, parentRef, variableName)
|
resp, err = h.configstoreClient.DeleteProjectVariable(ctx, parentRef, variableName)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if httpErrorFromRemote(w, resp, err) {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
|
||||||
http.Error(w, err.Error(), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
httpError(w, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
|
if err := httpResponse(w, http.StatusNoContent, nil); err != nil {
|
||||||
h.log.Errorf("err: %+v", err)
|
h.log.Errorf("err: %+v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,12 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
"github.com/sorintlab/agola/internal/services/gateway/common"
|
"github.com/sorintlab/agola/internal/services/gateway/common"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -38,3 +42,21 @@ func NewCommandHandler(logger *zap.Logger, sd *common.TokenSigningData, configst
|
||||||
webExposedURL: webExposedURL,
|
webExposedURL: webExposedURL,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ErrFromRemote(resp *http.Response, err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp != nil {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
// remove wrapping from errors sent to client
|
||||||
|
case http.StatusBadRequest:
|
||||||
|
return util.NewErrBadRequest(errors.Cause(err))
|
||||||
|
case http.StatusNotFound:
|
||||||
|
return util.NewErrNotFound(errors.Cause(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ func (c *CommandHandler) CreateOrg(ctx context.Context, req *CreateOrgRequest) (
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("creating organization")
|
c.log.Infof("creating organization")
|
||||||
org, _, err := c.configstoreClient.CreateOrg(ctx, org)
|
org, resp, err := c.configstoreClient.CreateOrg(ctx, org)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create organization")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create organization"))
|
||||||
}
|
}
|
||||||
c.log.Infof("organization %s created, ID: %s", org.Name, org.ID)
|
c.log.Infof("organization %s created, ID: %s", org.Name, org.ID)
|
||||||
|
|
||||||
|
|
|
@ -40,13 +40,15 @@ func (c *CommandHandler) CreateProject(ctx context.Context, req *CreateProjectRe
|
||||||
return nil, util.NewErrBadRequest(errors.Errorf("invalid project name %q", req.Name))
|
return nil, util.NewErrBadRequest(errors.Errorf("invalid project name %q", req.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
user, _, err := c.configstoreClient.GetUser(ctx, req.CurrentUserID)
|
user, resp, err := c.configstoreClient.GetUser(ctx, req.CurrentUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get user %q", req.CurrentUserID)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get user %q", req.CurrentUserID))
|
||||||
}
|
}
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
|
||||||
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName)
|
c.log.Errorf("err: %+v", err)
|
||||||
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
var la *types.LinkedAccount
|
var la *types.LinkedAccount
|
||||||
|
@ -101,9 +103,9 @@ func (c *CommandHandler) CreateProject(ctx context.Context, req *CreateProjectRe
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("creating project")
|
c.log.Infof("creating project")
|
||||||
p, _, err = c.configstoreClient.CreateProject(ctx, p)
|
p, resp, err = c.configstoreClient.CreateProject(ctx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create project")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create project"))
|
||||||
}
|
}
|
||||||
c.log.Infof("project %s created, ID: %s", p.Name, p.ID)
|
c.log.Infof("project %s created, ID: %s", p.Name, p.ID)
|
||||||
|
|
||||||
|
@ -152,14 +154,14 @@ func (c *CommandHandler) SetupProject(ctx context.Context, rs *types.RemoteSourc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandHandler) ReconfigProject(ctx context.Context, projectRef string) error {
|
func (c *CommandHandler) ReconfigProject(ctx context.Context, projectRef string) error {
|
||||||
p, _, err := c.configstoreClient.GetProject(ctx, projectRef)
|
p, resp, err := c.configstoreClient.GetProject(ctx, projectRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return ErrFromRemote(resp, errors.Wrapf(err, "failed to get project %q", projectRef))
|
||||||
}
|
}
|
||||||
|
|
||||||
user, _, err := c.configstoreClient.GetUserByLinkedAccount(ctx, p.LinkedAccountID)
|
user, resp, err := c.configstoreClient.GetUserByLinkedAccount(ctx, p.LinkedAccountID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to get user with linked account id %q", p.LinkedAccountID)
|
return ErrFromRemote(resp, errors.Wrapf(err, "failed to get user with linked account id %q", p.LinkedAccountID))
|
||||||
}
|
}
|
||||||
|
|
||||||
la := user.LinkedAccounts[p.LinkedAccountID]
|
la := user.LinkedAccounts[p.LinkedAccountID]
|
||||||
|
@ -168,9 +170,9 @@ func (c *CommandHandler) ReconfigProject(ctx context.Context, projectRef string)
|
||||||
return errors.Errorf("linked account %q in user %q doesn't exist", p.LinkedAccountID, user.UserName)
|
return errors.Errorf("linked account %q in user %q doesn't exist", p.LinkedAccountID, user.UserName)
|
||||||
}
|
}
|
||||||
|
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID)
|
rs, resp, err := c.configstoreClient.GetRemoteSource(ctx, la.RemoteSourceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to get remote source %q", la.RemoteSourceID)
|
return ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", la.RemoteSourceID))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SetupProject(ctx, rs, la, &SetupProjectRequest{
|
return c.SetupProject(ctx, rs, la, &SetupProjectRequest{
|
||||||
|
|
|
@ -35,9 +35,9 @@ func (c *CommandHandler) CreateProjectGroup(ctx context.Context, req *CreateProj
|
||||||
return nil, util.NewErrBadRequest(errors.Errorf("invalid projectGroup name %q", req.Name))
|
return nil, util.NewErrBadRequest(errors.Errorf("invalid projectGroup name %q", req.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
user, _, err := c.configstoreClient.GetUser(ctx, req.CurrentUserID)
|
user, resp, err := c.configstoreClient.GetUser(ctx, req.CurrentUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get user %q", req.CurrentUserID)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get user %q", req.CurrentUserID))
|
||||||
}
|
}
|
||||||
|
|
||||||
parentID := req.ParentID
|
parentID := req.ParentID
|
||||||
|
@ -55,9 +55,9 @@ func (c *CommandHandler) CreateProjectGroup(ctx context.Context, req *CreateProj
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("creating projectGroup")
|
c.log.Infof("creating projectGroup")
|
||||||
p, _, err = c.configstoreClient.CreateProjectGroup(ctx, p)
|
p, resp, err = c.configstoreClient.CreateProjectGroup(ctx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create projectGroup")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create projectGroup"))
|
||||||
}
|
}
|
||||||
c.log.Infof("projectGroup %s created, ID: %s", p.Name, p.ID)
|
c.log.Infof("projectGroup %s created, ID: %s", p.Name, p.ID)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright 2019 Sorint.lab
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sorintlab/agola/internal/services/gateway/common"
|
||||||
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
"github.com/sorintlab/agola/internal/util"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateRemoteSourceRequest struct {
|
||||||
|
Name string
|
||||||
|
APIURL string
|
||||||
|
Type string
|
||||||
|
AuthType string
|
||||||
|
Oauth2ClientID string
|
||||||
|
Oauth2ClientSecret string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandHandler) CreateRemoteSource(ctx context.Context, req *CreateRemoteSourceRequest) (*types.RemoteSource, error) {
|
||||||
|
if !util.ValidateName(req.Name) {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("invalid remotesource name %q", req.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Name == "" {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource name required"))
|
||||||
|
}
|
||||||
|
if req.APIURL == "" {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource api url required"))
|
||||||
|
}
|
||||||
|
if req.Type == "" {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource type required"))
|
||||||
|
}
|
||||||
|
if req.AuthType == "" {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource auth type required"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate if the remote source type supports the required auth type
|
||||||
|
if !common.SourceSupportsAuthType(types.RemoteSourceType(req.Type), types.RemoteSourceAuthType(req.AuthType)) {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource type %q doesn't support auth type %q", req.Type, req.AuthType))
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.AuthType == string(types.RemoteSourceAuthTypeOauth2) {
|
||||||
|
if req.Oauth2ClientID == "" {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource oauth2 clientid required"))
|
||||||
|
}
|
||||||
|
if req.Oauth2ClientSecret == "" {
|
||||||
|
return nil, util.NewErrBadRequest(errors.Errorf("remotesource oauth2 client secret required"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rs := &types.RemoteSource{
|
||||||
|
Name: req.Name,
|
||||||
|
Type: types.RemoteSourceType(req.Type),
|
||||||
|
AuthType: types.RemoteSourceAuthType(req.AuthType),
|
||||||
|
APIURL: req.APIURL,
|
||||||
|
Oauth2ClientID: req.Oauth2ClientID,
|
||||||
|
Oauth2ClientSecret: req.Oauth2ClientSecret,
|
||||||
|
}
|
||||||
|
|
||||||
|
c.log.Infof("creating remotesource")
|
||||||
|
rs, resp, err := c.configstoreClient.CreateRemoteSource(ctx, rs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create remotesource"))
|
||||||
|
}
|
||||||
|
c.log.Infof("remotesource %s created, ID: %s", rs.Name, rs.ID)
|
||||||
|
|
||||||
|
return rs, nil
|
||||||
|
}
|
|
@ -17,7 +17,6 @@ package command
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
gitsource "github.com/sorintlab/agola/internal/gitsources"
|
gitsource "github.com/sorintlab/agola/internal/gitsources"
|
||||||
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
|
||||||
|
@ -46,9 +45,9 @@ func (c *CommandHandler) CreateUser(ctx context.Context, req *CreateUserRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("creating user")
|
c.log.Infof("creating user")
|
||||||
u, _, err := c.configstoreClient.CreateUser(ctx, creq)
|
u, resp, err := c.configstoreClient.CreateUser(ctx, creq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create user")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create user"))
|
||||||
}
|
}
|
||||||
c.log.Infof("user %s created, ID: %s", u.UserName, u.ID)
|
c.log.Infof("user %s created, ID: %s", u.UserName, u.ID)
|
||||||
|
|
||||||
|
@ -76,10 +75,7 @@ func (c *CommandHandler) CreateUserToken(ctx context.Context, req *CreateUserTok
|
||||||
userName := req.UserName
|
userName := req.UserName
|
||||||
user, resp, err := c.configstoreClient.GetUserByName(ctx, userName)
|
user, resp, err := c.configstoreClient.GetUserByName(ctx, userName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
return "", ErrFromRemote(resp, errors.Wrapf(err, "failed to get user"))
|
||||||
return "", util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", userID))
|
|
||||||
}
|
|
||||||
return "", errors.Wrapf(err, "failed to get user %q", userID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// only admin or the same logged user can create a token
|
// only admin or the same logged user can create a token
|
||||||
|
@ -94,9 +90,9 @@ func (c *CommandHandler) CreateUserToken(ctx context.Context, req *CreateUserTok
|
||||||
creq := &csapi.CreateUserTokenRequest{
|
creq := &csapi.CreateUserTokenRequest{
|
||||||
TokenName: req.TokenName,
|
TokenName: req.TokenName,
|
||||||
}
|
}
|
||||||
res, _, err := c.configstoreClient.CreateUserToken(ctx, userName, creq)
|
res, resp, err := c.configstoreClient.CreateUserToken(ctx, userName, creq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "failed to create user token")
|
return "", ErrFromRemote(resp, errors.Wrapf(err, "failed to create user token"))
|
||||||
}
|
}
|
||||||
c.log.Infof("token %q for user %q created", req.TokenName, userName)
|
c.log.Infof("token %q for user %q created", req.TokenName, userName)
|
||||||
|
|
||||||
|
@ -115,14 +111,11 @@ func (c *CommandHandler) CreateUserLA(ctx context.Context, req *CreateUserLARequ
|
||||||
userName := req.UserName
|
userName := req.UserName
|
||||||
user, resp, err := c.configstoreClient.GetUserByName(ctx, userName)
|
user, resp, err := c.configstoreClient.GetUserByName(ctx, userName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get user %q", userName))
|
||||||
return nil, util.NewErrBadRequest(errors.Errorf("user %q doesn't exist", userName))
|
|
||||||
}
|
}
|
||||||
return nil, errors.Wrapf(err, "failed to get user %q", userName)
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
||||||
}
|
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
var la *types.LinkedAccount
|
var la *types.LinkedAccount
|
||||||
|
@ -164,9 +157,9 @@ func (c *CommandHandler) CreateUserLA(ctx context.Context, req *CreateUserLARequ
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("creating linked account")
|
c.log.Infof("creating linked account")
|
||||||
la, _, err = c.configstoreClient.CreateUserLA(ctx, userName, creq)
|
la, resp, err = c.configstoreClient.CreateUserLA(ctx, userName, creq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create linked account")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create linked account"))
|
||||||
}
|
}
|
||||||
c.log.Infof("linked account %q for user %q created", la.ID, userName)
|
c.log.Infof("linked account %q for user %q created", la.ID, userName)
|
||||||
|
|
||||||
|
@ -189,9 +182,9 @@ func (c *CommandHandler) RegisterUser(ctx context.Context, req *RegisterUserRequ
|
||||||
return nil, util.NewErrBadRequest(errors.Errorf("invalid user name %q", req.UserName))
|
return nil, util.NewErrBadRequest(errors.Errorf("invalid user name %q", req.UserName))
|
||||||
}
|
}
|
||||||
|
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
|
|
||||||
|
@ -225,9 +218,9 @@ func (c *CommandHandler) RegisterUser(ctx context.Context, req *RegisterUserRequ
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("creating user account")
|
c.log.Infof("creating user account")
|
||||||
u, _, err := c.configstoreClient.CreateUser(ctx, creq)
|
u, resp, err := c.configstoreClient.CreateUser(ctx, creq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create linked account")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to create linked account"))
|
||||||
}
|
}
|
||||||
c.log.Infof("user %q created", req.UserName)
|
c.log.Infof("user %q created", req.UserName)
|
||||||
|
|
||||||
|
@ -247,9 +240,9 @@ type LoginUserResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*LoginUserResponse, error) {
|
func (c *CommandHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*LoginUserResponse, error) {
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
|
|
||||||
|
@ -270,9 +263,9 @@ func (c *CommandHandler) 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, _, err := c.configstoreClient.GetUserByLinkedAccountRemoteUserAndSource(ctx, remoteUserInfo.ID, rs.ID)
|
user, resp, err := c.configstoreClient.GetUserByLinkedAccountRemoteUserAndSource(ctx, remoteUserInfo.ID, rs.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get user for remote user id %q and remote source %q", remoteUserInfo.ID, rs.ID)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get user for remote user id %q and remote source %q", remoteUserInfo.ID, rs.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
var la *types.LinkedAccount
|
var la *types.LinkedAccount
|
||||||
|
@ -305,9 +298,9 @@ func (c *CommandHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (
|
||||||
}
|
}
|
||||||
|
|
||||||
c.log.Infof("updating user %q linked account", user.UserName)
|
c.log.Infof("updating user %q linked account", user.UserName)
|
||||||
la, _, err = c.configstoreClient.UpdateUserLA(ctx, user.UserName, la.ID, creq)
|
la, resp, err = c.configstoreClient.UpdateUserLA(ctx, user.UserName, la.ID, creq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to update user")
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to update user"))
|
||||||
}
|
}
|
||||||
c.log.Infof("linked account %q for user %q updated", la.ID, user.UserName)
|
c.log.Infof("linked account %q for user %q updated", la.ID, user.UserName)
|
||||||
}
|
}
|
||||||
|
@ -336,9 +329,9 @@ type AuthorizeResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandHandler) Authorize(ctx context.Context, req *AuthorizeRequest) (*AuthorizeResponse, error) {
|
func (c *CommandHandler) Authorize(ctx context.Context, req *AuthorizeRequest) (*AuthorizeResponse, error) {
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, req.RemoteSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", req.RemoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
|
|
||||||
|
@ -371,18 +364,18 @@ type RemoteSourceAuthResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommandHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSourceName, loginName, loginPassword string, requestType RemoteSourceRequestType, req interface{}) (*RemoteSourceAuthResponse, error) {
|
func (c *CommandHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSourceName, loginName, loginPassword string, requestType RemoteSourceRequestType, req interface{}) (*RemoteSourceAuthResponse, error) {
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, remoteSourceName)
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, remoteSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", remoteSourceName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", remoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
|
|
||||||
switch requestType {
|
switch requestType {
|
||||||
case RemoteSourceRequestTypeCreateUserLA:
|
case RemoteSourceRequestTypeCreateUserLA:
|
||||||
req := req.(*CreateUserLARequest)
|
req := req.(*CreateUserLARequest)
|
||||||
user, _, err := c.configstoreClient.GetUserByName(ctx, req.UserName)
|
user, resp, err := c.configstoreClient.GetUserByName(ctx, req.UserName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get user %q", req.UserName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get user %q", req.UserName))
|
||||||
}
|
}
|
||||||
var la *types.LinkedAccount
|
var la *types.LinkedAccount
|
||||||
for _, v := range user.LinkedAccounts {
|
for _, v := range user.LinkedAccounts {
|
||||||
|
@ -393,7 +386,7 @@ func (c *CommandHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSourc
|
||||||
}
|
}
|
||||||
c.log.Infof("la: %s", util.Dump(la))
|
c.log.Infof("la: %s", util.Dump(la))
|
||||||
if la != nil {
|
if la != nil {
|
||||||
return nil, errors.Errorf("user %q already have a linked account for remote source %q", req.UserName, rs.Name)
|
return nil, util.NewErrBadRequest(errors.Errorf("user %q already have a linked account for remote source %q", req.UserName, rs.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
case RemoteSourceRequestTypeLoginUser:
|
case RemoteSourceRequestTypeLoginUser:
|
||||||
|
@ -594,9 +587,9 @@ func (c *CommandHandler) HandleOauth2Callback(ctx context.Context, code, state s
|
||||||
requestType := RemoteSourceRequestType(claims["request_type"].(string))
|
requestType := RemoteSourceRequestType(claims["request_type"].(string))
|
||||||
requestString := claims["request"].(string)
|
requestString := claims["request"].(string)
|
||||||
|
|
||||||
rs, _, err := c.configstoreClient.GetRemoteSourceByName(ctx, remoteSourceName)
|
rs, resp, err := c.configstoreClient.GetRemoteSourceByName(ctx, remoteSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to get remote source %q", remoteSourceName)
|
return nil, ErrFromRemote(resp, errors.Wrapf(err, "failed to get remote source %q", remoteSourceName))
|
||||||
}
|
}
|
||||||
c.log.Infof("rs: %s", util.Dump(rs))
|
c.log.Infof("rs: %s", util.Dump(rs))
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ func (g *Gateway) Run(ctx context.Context) error {
|
||||||
deleteUserTokenHandler := api.NewDeleteUserTokenHandler(logger, g.configstoreClient)
|
deleteUserTokenHandler := api.NewDeleteUserTokenHandler(logger, g.configstoreClient)
|
||||||
|
|
||||||
remoteSourceHandler := api.NewRemoteSourceHandler(logger, g.configstoreClient)
|
remoteSourceHandler := api.NewRemoteSourceHandler(logger, g.configstoreClient)
|
||||||
createRemoteSourceHandler := api.NewCreateRemoteSourceHandler(logger, g.configstoreClient)
|
createRemoteSourceHandler := api.NewCreateRemoteSourceHandler(logger, g.ch)
|
||||||
remoteSourcesHandler := api.NewRemoteSourcesHandler(logger, g.configstoreClient)
|
remoteSourcesHandler := api.NewRemoteSourcesHandler(logger, g.configstoreClient)
|
||||||
|
|
||||||
orgHandler := api.NewOrgHandler(logger, g.configstoreClient)
|
orgHandler := api.NewOrgHandler(logger, g.configstoreClient)
|
||||||
|
|
|
@ -44,7 +44,10 @@ type ErrorResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrorResponseFromError(err error) *ErrorResponse {
|
func ErrorResponseFromError(err error) *ErrorResponse {
|
||||||
if util.IsErrBadRequest(err) {
|
switch {
|
||||||
|
case util.IsErrBadRequest(err):
|
||||||
|
fallthrough
|
||||||
|
case util.IsErrNotFound(err):
|
||||||
return &ErrorResponse{Message: err.Error()}
|
return &ErrorResponse{Message: err.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,26 +56,30 @@ func ErrorResponseFromError(err error) *ErrorResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
func httpError(w http.ResponseWriter, err error) bool {
|
func httpError(w http.ResponseWriter, err error) bool {
|
||||||
if err != nil {
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
response := ErrorResponseFromError(err)
|
response := ErrorResponseFromError(err)
|
||||||
resj, merr := json.Marshal(response)
|
resj, merr := json.Marshal(response)
|
||||||
if merr != nil {
|
if merr != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if util.IsErrBadRequest(err) {
|
switch {
|
||||||
|
case util.IsErrBadRequest(err):
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write(resj)
|
w.Write(resj)
|
||||||
} else {
|
case util.IsErrNotFound(err):
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
w.Write(resj)
|
||||||
|
default:
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write(resj)
|
w.Write(resj)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
func httpResponse(w http.ResponseWriter, code int, res interface{}) error {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
|
|
@ -80,16 +80,14 @@ func (c *Client) getResponse(ctx context.Context, method, path string, query url
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) <= 1 {
|
errMap := make(map[string]interface{})
|
||||||
return resp, errors.New(resp.Status)
|
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))
|
||||||
// TODO(sgotti) use a json error response
|
|
||||||
|
|
||||||
return resp, errors.New(string(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ type ErrBadRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrBadRequest) Error() string {
|
func (e *ErrBadRequest) Error() string {
|
||||||
return fmt.Sprintf("bad request: %s", e.Err.Error())
|
return e.Err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewErrBadRequest(err error) *ErrBadRequest {
|
func NewErrBadRequest(err error) *ErrBadRequest {
|
||||||
|
@ -75,3 +74,22 @@ func IsErrBadRequest(err error) bool {
|
||||||
_, ok := err.(*ErrBadRequest)
|
_, ok := err.(*ErrBadRequest)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrNotFound represent a not found error
|
||||||
|
// it's used to differentiate an internal error from an user error
|
||||||
|
type ErrNotFound struct {
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrNotFound) Error() string {
|
||||||
|
return e.Err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrNotFound(err error) *ErrNotFound {
|
||||||
|
return &ErrNotFound{Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrNotFound(err error) bool {
|
||||||
|
_, ok := err.(*ErrNotFound)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
|
@ -142,11 +142,11 @@ func (g *Git) Pipe(ctx context.Context, w io.Writer, r io.Reader, args ...string
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrNotFound struct {
|
type ErrGitKeyNotFound struct {
|
||||||
Key string
|
Key string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrNotFound) Error() string {
|
func (e *ErrGitKeyNotFound) Error() string {
|
||||||
return fmt.Sprintf("key `%q` was not found", e.Key)
|
return fmt.Sprintf("key `%q` was not found", e.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ func (g *Git) ConfigGet(ctx context.Context, args ...string) (string, error) {
|
||||||
if exitError, ok := err.(*exec.ExitError); ok {
|
if exitError, ok := err.(*exec.ExitError); ok {
|
||||||
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
|
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
|
||||||
if waitStatus.ExitStatus() == 1 {
|
if waitStatus.ExitStatus() == 1 {
|
||||||
return "", &ErrNotFound{Key: args[len(args)-1]}
|
return "", &ErrGitKeyNotFound{Key: args[len(args)-1]}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -173,7 +173,7 @@ func (g *Git) ConfigSet(ctx context.Context, args ...string) (string, error) {
|
||||||
if exitError, ok := err.(*exec.ExitError); ok {
|
if exitError, ok := err.(*exec.ExitError); ok {
|
||||||
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
|
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
|
||||||
if waitStatus.ExitStatus() == 1 {
|
if waitStatus.ExitStatus() == 1 {
|
||||||
return "", &ErrNotFound{Key: args[len(args)-1]}
|
return "", &ErrGitKeyNotFound{Key: args[len(args)-1]}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", err
|
return "", err
|
||||||
|
|
Loading…
Reference in New Issue