Apigw tweaks
- Add system/apigw tests - Removes permissions from APIGw filters from each level
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
rbac:
|
||||
operations:
|
||||
read:
|
||||
description: Read API Gateway filter
|
||||
update:
|
||||
description: Update API Gateway filter
|
||||
delete:
|
||||
description: Delete API Gateway filter
|
||||
@@ -60,10 +60,5 @@ rbac:
|
||||
apigw-routes.search:
|
||||
description: List search or filter API gateway routes
|
||||
|
||||
apigw-filter.create:
|
||||
description: Add API gateway filter to route
|
||||
apigw-filters.search:
|
||||
description: List, search or filter API gateway filters
|
||||
|
||||
resource-translations.manage:
|
||||
description: List, search, create, or update resource translations
|
||||
|
||||
@@ -113,23 +113,23 @@ func NewDefaultJsonResponse() (e *defaultJsonResponse) {
|
||||
return
|
||||
}
|
||||
|
||||
func (h defaultJsonResponse) New() types.Handler {
|
||||
func (j defaultJsonResponse) New() types.Handler {
|
||||
return NewDefaultJsonResponse()
|
||||
}
|
||||
|
||||
func (h defaultJsonResponse) String() string {
|
||||
return fmt.Sprintf("apigw filter %s (%s)", h.Name, h.Label)
|
||||
func (j defaultJsonResponse) String() string {
|
||||
return fmt.Sprintf("apigw filter %s (%s)", j.Name, j.Label)
|
||||
}
|
||||
|
||||
func (h defaultJsonResponse) Meta() types.FilterMeta {
|
||||
return h.FilterMeta
|
||||
func (j defaultJsonResponse) Meta() types.FilterMeta {
|
||||
return j.FilterMeta
|
||||
}
|
||||
|
||||
func (f *defaultJsonResponse) Merge(params []byte) (h types.Handler, err error) {
|
||||
return f, err
|
||||
func (j *defaultJsonResponse) Merge(params []byte) (h types.Handler, err error) {
|
||||
return j, err
|
||||
}
|
||||
|
||||
func (h defaultJsonResponse) Handler() types.HandlerFunc {
|
||||
func (j defaultJsonResponse) Handler() types.HandlerFunc {
|
||||
return func(rw http.ResponseWriter, r *http.Request) error {
|
||||
rw.Header().Set("Content-Type", "application/json")
|
||||
rw.WriteHeader(http.StatusAccepted)
|
||||
|
||||
@@ -68,21 +68,21 @@ func (h header) Meta() types.FilterMeta {
|
||||
return h.FilterMeta
|
||||
}
|
||||
|
||||
func (v *header) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&v.params)
|
||||
func (h *header) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&h.params)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parser := expr.NewParser()
|
||||
v.eval, err = parser.Parse(v.params.Expr)
|
||||
h.eval, err = parser.Parse(h.params.Expr)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not validate origin parameters: %s", err)
|
||||
}
|
||||
|
||||
return v, err
|
||||
return h, err
|
||||
}
|
||||
|
||||
func (h header) Handler() types.HandlerFunc {
|
||||
@@ -137,36 +137,36 @@ func NewQueryParam() (v *queryParam) {
|
||||
return
|
||||
}
|
||||
|
||||
func (h queryParam) New() types.Handler {
|
||||
func (qp queryParam) New() types.Handler {
|
||||
return NewQueryParam()
|
||||
}
|
||||
|
||||
func (h queryParam) String() string {
|
||||
return fmt.Sprintf("apigw filter %s (%s)", h.Name, h.Label)
|
||||
func (qp queryParam) String() string {
|
||||
return fmt.Sprintf("apigw filter %s (%s)", qp.Name, qp.Label)
|
||||
}
|
||||
|
||||
func (h queryParam) Meta() types.FilterMeta {
|
||||
return h.FilterMeta
|
||||
func (qp queryParam) Meta() types.FilterMeta {
|
||||
return qp.FilterMeta
|
||||
}
|
||||
|
||||
func (v *queryParam) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&v.params)
|
||||
func (qp *queryParam) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&qp.params)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parser := expr.NewParser()
|
||||
v.eval, err = parser.Parse(v.params.Expr)
|
||||
qp.eval, err = parser.Parse(qp.params.Expr)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not validate query parameters: %s", err)
|
||||
}
|
||||
|
||||
return v, err
|
||||
return qp, err
|
||||
}
|
||||
|
||||
func (h *queryParam) Handler() types.HandlerFunc {
|
||||
func (qp *queryParam) Handler() types.HandlerFunc {
|
||||
return func(rw http.ResponseWriter, r *http.Request) error {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
@@ -183,17 +183,17 @@ func (h *queryParam) Handler() types.HandlerFunc {
|
||||
out, err := expr.NewVars(vv)
|
||||
|
||||
if err != nil {
|
||||
return pe.Internal("could not validate query parameters: (%v) (%s)", err, h.params.Expr)
|
||||
return pe.Internal("could not validate query parameters: (%v) (%s)", err, qp.params.Expr)
|
||||
}
|
||||
|
||||
b, err := h.eval.Test(ctx, out)
|
||||
b, err := qp.eval.Test(ctx, out)
|
||||
|
||||
if err != nil {
|
||||
return pe.InvalidData("could not validate query parameters: (%v) (%s)", err, h.params.Expr)
|
||||
return pe.InvalidData("could not validate query parameters: (%v) (%s)", err, qp.params.Expr)
|
||||
}
|
||||
|
||||
if !b {
|
||||
return pe.InvalidData("could not validate query parameters: (%v) (%s)", errors.New("validation failed"), h.params.Expr)
|
||||
return pe.InvalidData("could not validate query parameters: (%v) (%s)", errors.New("validation failed"), qp.params.Expr)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -77,10 +77,10 @@ func (h workflow) Meta() types.FilterMeta {
|
||||
return h.FilterMeta
|
||||
}
|
||||
|
||||
func (f *workflow) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&f.params)
|
||||
func (h *workflow) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&h.params)
|
||||
|
||||
return f, err
|
||||
return h, err
|
||||
}
|
||||
|
||||
func (h workflow) Handler() types.HandlerFunc {
|
||||
|
||||
@@ -79,21 +79,21 @@ func (h proxy) Meta() types.FilterMeta {
|
||||
return h.FilterMeta
|
||||
}
|
||||
|
||||
func (f *proxy) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&f.params)
|
||||
func (h *proxy) Merge(params []byte) (types.Handler, error) {
|
||||
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&h.params)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get the auth mechanism
|
||||
f.a, err = NewProxyAuthServicer(f.c, f.params.Auth, f.s)
|
||||
h.a, err = NewProxyAuthServicer(h.c, h.params.Auth, h.s)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not load auth servicer for proxying: %s", err)
|
||||
}
|
||||
|
||||
return f, err
|
||||
return h, err
|
||||
}
|
||||
|
||||
func (h proxy) Handler() types.HandlerFunc {
|
||||
|
||||
@@ -80,21 +80,21 @@ type (
|
||||
func NewProxyAuthServicer(c *http.Client, p ProxyAuthParams, s types.SecureStorager) (ProxyAuthServicer, error) {
|
||||
switch p.Type {
|
||||
case proxyAuthTypeHeader:
|
||||
return NewProxyAuthHeader(p)
|
||||
return newProxyAuthHeader(p)
|
||||
case proxyAuthTypeQuery:
|
||||
return NewProxyAuthQuery(p)
|
||||
return newProxyAuthQuery(p)
|
||||
case proxyAuthTypeBasic:
|
||||
return NewProxyAuthBasic(p)
|
||||
return newProxyAuthBasic(p)
|
||||
case proxyAuthTypeOauth2:
|
||||
return NewProxyAuthOauth2(p, c, s)
|
||||
return newProxyAuthOauth2(p, c, s)
|
||||
case proxyAuthTypeJWT:
|
||||
return NewProxyAuthJWT(p)
|
||||
return newProxyAuthJWT(p)
|
||||
default:
|
||||
return proxyAuthServicerNoop{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func NewProxyAuthHeader(p ProxyAuthParams) (s proxyAuthServicerHeader, err error) {
|
||||
func newProxyAuthHeader(p ProxyAuthParams) (s proxyAuthServicerHeader, err error) {
|
||||
s = proxyAuthServicerHeader{
|
||||
params: p.Params,
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func NewProxyAuthHeader(p ProxyAuthParams) (s proxyAuthServicerHeader, err error
|
||||
return
|
||||
}
|
||||
|
||||
func NewProxyAuthQuery(p ProxyAuthParams) (s proxyAuthServicerQuery, err error) {
|
||||
func newProxyAuthQuery(p ProxyAuthParams) (s proxyAuthServicerQuery, err error) {
|
||||
s = proxyAuthServicerQuery{
|
||||
params: p.Params,
|
||||
}
|
||||
@@ -110,7 +110,7 @@ func NewProxyAuthQuery(p ProxyAuthParams) (s proxyAuthServicerQuery, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func NewProxyAuthBasic(p ProxyAuthParams) (s proxyAuthServicerBasic, err error) {
|
||||
func newProxyAuthBasic(p ProxyAuthParams) (s proxyAuthServicerBasic, err error) {
|
||||
var (
|
||||
ok bool
|
||||
user, pass string
|
||||
@@ -136,7 +136,7 @@ func NewProxyAuthBasic(p ProxyAuthParams) (s proxyAuthServicerBasic, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func NewProxyAuthOauth2(p ProxyAuthParams, c *http.Client, s types.SecureStorager) (ss proxyAuthServicerOauth2, err error) {
|
||||
func newProxyAuthOauth2(p ProxyAuthParams, c *http.Client, s types.SecureStorager) (ss proxyAuthServicerOauth2, err error) {
|
||||
var (
|
||||
u *url.URL
|
||||
ok bool
|
||||
@@ -182,7 +182,7 @@ func NewProxyAuthOauth2(p ProxyAuthParams, c *http.Client, s types.SecureStorage
|
||||
return
|
||||
}
|
||||
|
||||
func NewProxyAuthJWT(p ProxyAuthParams) (ss proxyAuthServicerJWT, err error) {
|
||||
func newProxyAuthJWT(p ProxyAuthParams) (ss proxyAuthServicerJWT, err error) {
|
||||
var (
|
||||
ok bool
|
||||
jwt string
|
||||
|
||||
@@ -175,7 +175,8 @@ func Test_proxy(t *testing.T) {
|
||||
}
|
||||
|
||||
proxy := New(zap.NewNop(), c, struct{}{})
|
||||
proxy.Merge([]byte(tc.params))
|
||||
_, err := proxy.Merge([]byte(tc.params))
|
||||
req.NoError(err)
|
||||
|
||||
scope := &types.Scp{
|
||||
"opts": options.Apigw(),
|
||||
@@ -185,7 +186,7 @@ func Test_proxy(t *testing.T) {
|
||||
rq = rq.WithContext(ctx)
|
||||
|
||||
hn := proxy.Handler()
|
||||
err := hn(rc, rq)
|
||||
err = hn(rc, rq)
|
||||
|
||||
if tc.err != "" {
|
||||
req.EqualError(err, tc.err)
|
||||
|
||||
@@ -50,7 +50,7 @@ func (pp *Pl) Error() types.ErrorHandlerFunc {
|
||||
return pp.err
|
||||
}
|
||||
|
||||
// add error handler
|
||||
// ErrorHandler adds error handler
|
||||
func (pp *Pl) ErrorHandler(ff types.ErrorHandlerFunc) {
|
||||
pp.err = ff
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func (s *apigw) Router(r chi.Router) {
|
||||
}()
|
||||
}
|
||||
|
||||
// init all the routes
|
||||
// Init all the routes
|
||||
func (s *apigw) Init(ctx context.Context, route ...*route) {
|
||||
var (
|
||||
defaultPostFilter types.Handler
|
||||
@@ -240,7 +240,7 @@ func (s *apigw) Init(ctx context.Context, route ...*route) {
|
||||
r.handler = pipe.Handler()
|
||||
r.errHandler = pipe.Error()
|
||||
|
||||
log.Debug("successfuly registered route")
|
||||
log.Debug("successfully registered route")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
pkg/envoy/resource/rbac_references_system.gen.go
generated
14
pkg/envoy/resource/rbac_references_system.gen.go
generated
@@ -7,7 +7,6 @@ package resource
|
||||
//
|
||||
|
||||
// Definitions file that controls how this file is generated:
|
||||
// - system.apigw-filter.yaml
|
||||
// - system.apigw-route.yaml
|
||||
// - system.application.yaml
|
||||
// - system.auth-client.yaml
|
||||
@@ -21,19 +20,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
)
|
||||
|
||||
// SystemApigwFilterRbacReferences generates RBAC references
|
||||
//
|
||||
// Resources with "envoy: false" are skipped
|
||||
//
|
||||
// This function is auto-generated
|
||||
func SystemApigwFilterRbacReferences(apigwFilter string) (res *Ref, pp []*Ref, err error) {
|
||||
if apigwFilter != "*" {
|
||||
res = &Ref{ResourceType: types.ApigwFilterResourceType, Identifiers: MakeIdentifiers(apigwFilter)}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SystemApigwRouteRbacReferences generates RBAC references
|
||||
//
|
||||
// Resources with "envoy: false" are skipped
|
||||
|
||||
11
pkg/envoy/resource/rbac_rules_parse.gen.go
generated
11
pkg/envoy/resource/rbac_rules_parse.gen.go
generated
@@ -16,7 +16,6 @@ package resource
|
||||
// - compose.page.yaml
|
||||
// - compose.record.yaml
|
||||
// - compose.yaml
|
||||
// - system.apigw-filter.yaml
|
||||
// - system.apigw-route.yaml
|
||||
// - system.application.yaml
|
||||
// - system.auth-client.yaml
|
||||
@@ -171,16 +170,6 @@ func ParseRule(res string) (string, *Ref, []*Ref, error) {
|
||||
|
||||
// Component resource, no path
|
||||
return composeTypes.ComponentResourceType, nil, nil, nil
|
||||
case systemTypes.ApigwFilterResourceType:
|
||||
if len(path) != 1 {
|
||||
return "", nil, nil, fmt.Errorf("expecting 1 reference components in path, got %d", len(path))
|
||||
}
|
||||
ref, pp, err := SystemApigwFilterRbacReferences(
|
||||
// apigwFilter
|
||||
path[0],
|
||||
)
|
||||
return systemTypes.ApigwFilterResourceType, ref, pp, err
|
||||
|
||||
case systemTypes.ApigwRouteResourceType:
|
||||
if len(path) != 1 {
|
||||
return "", nil, nil, fmt.Errorf("expecting 1 reference components in path, got %d", len(path))
|
||||
|
||||
@@ -37,8 +37,6 @@ allow:
|
||||
- application.flag.global
|
||||
- apigw-route.create
|
||||
- apigw-routes.search
|
||||
- apigw-filter.create
|
||||
- apigw-filters.search
|
||||
- report.create
|
||||
- reports.search
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ rdbms:
|
||||
|
||||
search:
|
||||
enablePaging: true
|
||||
enableFilterCheckFunction: false
|
||||
|
||||
upsert:
|
||||
enable: false
|
||||
|
||||
@@ -37,7 +37,6 @@ rdbms:
|
||||
|
||||
search:
|
||||
enablePaging: true
|
||||
enableFilterCheckFunction: false
|
||||
|
||||
upsert:
|
||||
enable: false
|
||||
|
||||
14
store/rdbms/apigw_filter.gen.go
generated
14
store/rdbms/apigw_filter.gen.go
generated
@@ -81,7 +81,7 @@ func (s Store) SearchApigwFilters(ctx context.Context, f types.ApigwFilterFilter
|
||||
ctx,
|
||||
q, f.Sort, f.PageCursor,
|
||||
f.Limit,
|
||||
nil,
|
||||
f.Check,
|
||||
func(cur *filter.PagingCursor) squirrel.Sqlizer {
|
||||
return builders.CursorCondition(cur, nil)
|
||||
},
|
||||
@@ -265,6 +265,16 @@ func (s Store) QueryApigwFilters(
|
||||
|
||||
for _, res = range tmp {
|
||||
|
||||
// check fn set, call it and see if it passed the test
|
||||
// if not, skip the item
|
||||
if check != nil {
|
||||
if chk, err := check(res); err != nil {
|
||||
return nil, err
|
||||
} else if !chk {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
set = append(set, res)
|
||||
}
|
||||
|
||||
@@ -465,7 +475,7 @@ func (Store) apigwFilterColumns(aa ...string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// {true true false true true false}
|
||||
// {true true false true true true}
|
||||
|
||||
// sortableApigwFilterColumns returns all ApigwFilter columns flagged as sortable
|
||||
//
|
||||
|
||||
14
store/rdbms/apigw_route.gen.go
generated
14
store/rdbms/apigw_route.gen.go
generated
@@ -81,7 +81,7 @@ func (s Store) SearchApigwRoutes(ctx context.Context, f types.ApigwRouteFilter)
|
||||
ctx,
|
||||
q, f.Sort, f.PageCursor,
|
||||
f.Limit,
|
||||
nil,
|
||||
f.Check,
|
||||
func(cur *filter.PagingCursor) squirrel.Sqlizer {
|
||||
return builders.CursorCondition(cur, nil)
|
||||
},
|
||||
@@ -265,6 +265,16 @@ func (s Store) QueryApigwRoutes(
|
||||
|
||||
for _, res = range tmp {
|
||||
|
||||
// check fn set, call it and see if it passed the test
|
||||
// if not, skip the item
|
||||
if check != nil {
|
||||
if chk, err := check(res); err != nil {
|
||||
return nil, err
|
||||
} else if !chk {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
set = append(set, res)
|
||||
}
|
||||
|
||||
@@ -465,7 +475,7 @@ func (Store) apigwRouteColumns(aa ...string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// {true true false true true false}
|
||||
// {true true false true true true}
|
||||
|
||||
// sortableApigwRouteColumns returns all ApigwRoute columns flagged as sortable
|
||||
//
|
||||
|
||||
@@ -1699,8 +1699,7 @@ endpoints:
|
||||
path: "/"
|
||||
parameters:
|
||||
get:
|
||||
- { name: routeID, type: "uint64", title: "Filter by route ID" }
|
||||
- { name: query, type: "string", title: "Filter filters" }
|
||||
- { name: routeID, type: "uint64", title: "Filter by route ID", required: true }
|
||||
- { name: deleted, type: "uint64", title: "Exclude (0, default), include (1) or return only (2) deleted filters" }
|
||||
- { name: disabled, type: "uint64", title: "Exclude (0, default), include (1) or return only (2) disabled filters" }
|
||||
- { name: limit, type: "uint", title: "Limit" }
|
||||
|
||||
@@ -40,11 +40,6 @@ type (
|
||||
// Filter by route ID
|
||||
RouteID uint64 `json:",string"`
|
||||
|
||||
// Query GET parameter
|
||||
//
|
||||
// Filter filters
|
||||
Query string
|
||||
|
||||
// Deleted GET parameter
|
||||
//
|
||||
// Exclude (0, default), include (1) or return only (2) deleted filters
|
||||
@@ -171,7 +166,6 @@ func NewApigwFilterList() *ApigwFilterList {
|
||||
func (r ApigwFilterList) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"routeID": r.RouteID,
|
||||
"query": r.Query,
|
||||
"deleted": r.Deleted,
|
||||
"disabled": r.Disabled,
|
||||
"limit": r.Limit,
|
||||
@@ -185,11 +179,6 @@ func (r ApigwFilterList) GetRouteID() uint64 {
|
||||
return r.RouteID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ApigwFilterList) GetQuery() string {
|
||||
return r.Query
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ApigwFilterList) GetDeleted() uint64 {
|
||||
return r.Deleted
|
||||
@@ -228,12 +217,6 @@ func (r *ApigwFilterList) Fill(req *http.Request) (err error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if val, ok := tmp["query"]; ok && len(val) > 0 {
|
||||
r.Query, err = val[0], nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if val, ok := tmp["deleted"]; ok && len(val) > 0 {
|
||||
r.Deleted, err = payload.ParseUint64(val[0]), nil
|
||||
if err != nil {
|
||||
|
||||
115
system/service/access_control.gen.go
generated
115
system/service/access_control.gen.go
generated
@@ -7,7 +7,6 @@ package service
|
||||
//
|
||||
|
||||
// Definitions file that controls how this file is generated:
|
||||
// - system.apigw-filter.yaml
|
||||
// - system.apigw-route.yaml
|
||||
// - system.application.yaml
|
||||
// - system.auth-client.yaml
|
||||
@@ -64,21 +63,6 @@ func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee
|
||||
|
||||
func (svc accessControl) List() (out []map[string]string) {
|
||||
def := []map[string]string{
|
||||
{
|
||||
"type": types.ApigwFilterResourceType,
|
||||
"any": types.ApigwFilterRbacResource(0),
|
||||
"op": "read",
|
||||
},
|
||||
{
|
||||
"type": types.ApigwFilterResourceType,
|
||||
"any": types.ApigwFilterRbacResource(0),
|
||||
"op": "update",
|
||||
},
|
||||
{
|
||||
"type": types.ApigwFilterResourceType,
|
||||
"any": types.ApigwFilterRbacResource(0),
|
||||
"op": "delete",
|
||||
},
|
||||
{
|
||||
"type": types.ApigwRouteResourceType,
|
||||
"any": types.ApigwRouteRbacResource(0),
|
||||
@@ -344,16 +328,6 @@ func (svc accessControl) List() (out []map[string]string) {
|
||||
"any": types.ComponentRbacResource(),
|
||||
"op": "apigw-routes.search",
|
||||
},
|
||||
{
|
||||
"type": types.ComponentResourceType,
|
||||
"any": types.ComponentRbacResource(),
|
||||
"op": "apigw-filter.create",
|
||||
},
|
||||
{
|
||||
"type": types.ComponentResourceType,
|
||||
"any": types.ComponentRbacResource(),
|
||||
"op": "apigw-filters.search",
|
||||
},
|
||||
{
|
||||
"type": types.ComponentResourceType,
|
||||
"any": types.ComponentRbacResource(),
|
||||
@@ -421,27 +395,6 @@ func (svc accessControl) FindRulesByRoleID(ctx context.Context, roleID uint64) (
|
||||
return svc.rbac.FindRulesByRoleID(roleID), nil
|
||||
}
|
||||
|
||||
// CanReadApigwFilter checks if current user can read api gateway filter
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) CanReadApigwFilter(ctx context.Context, r *types.ApigwFilter) bool {
|
||||
return svc.can(ctx, "read", r)
|
||||
}
|
||||
|
||||
// CanUpdateApigwFilter checks if current user can update api gateway filter
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) CanUpdateApigwFilter(ctx context.Context, r *types.ApigwFilter) bool {
|
||||
return svc.can(ctx, "update", r)
|
||||
}
|
||||
|
||||
// CanDeleteApigwFilter checks if current user can delete api gateway filter
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) CanDeleteApigwFilter(ctx context.Context, r *types.ApigwFilter) bool {
|
||||
return svc.can(ctx, "delete", r)
|
||||
}
|
||||
|
||||
// CanReadApigwRoute checks if current user can read api gateway route
|
||||
//
|
||||
// This function is auto-generated
|
||||
@@ -813,20 +766,6 @@ func (svc accessControl) CanSearchApigwRoutes(ctx context.Context) bool {
|
||||
return svc.can(ctx, "apigw-routes.search", &types.Component{})
|
||||
}
|
||||
|
||||
// CanCreateApigwFilter checks if current user can add api gateway filter to route
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) CanCreateApigwFilter(ctx context.Context) bool {
|
||||
return svc.can(ctx, "apigw-filter.create", &types.Component{})
|
||||
}
|
||||
|
||||
// CanSearchApigwFilters checks if current user can list, search or filter api gateway filters
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) CanSearchApigwFilters(ctx context.Context) bool {
|
||||
return svc.can(ctx, "apigw-filters.search", &types.Component{})
|
||||
}
|
||||
|
||||
// CanManageResourceTranslations checks if current user can list, search, create, or update resource translations
|
||||
//
|
||||
// This function is auto-generated
|
||||
@@ -839,8 +778,6 @@ func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool
|
||||
// This function is auto-generated
|
||||
func rbacResourceValidator(r string, oo ...string) error {
|
||||
switch rbac.ResourceType(r) {
|
||||
case types.ApigwFilterResourceType:
|
||||
return rbacApigwFilterResourceValidator(r, oo...)
|
||||
case types.ApigwRouteResourceType:
|
||||
return rbacApigwRouteResourceValidator(r, oo...)
|
||||
case types.ApplicationResourceType:
|
||||
@@ -867,12 +804,6 @@ func rbacResourceValidator(r string, oo ...string) error {
|
||||
// This function is auto-generated
|
||||
func rbacResourceOperations(r string) map[string]bool {
|
||||
switch rbac.ResourceType(r) {
|
||||
case types.ApigwFilterResourceType:
|
||||
return map[string]bool{
|
||||
"read": true,
|
||||
"update": true,
|
||||
"delete": true,
|
||||
}
|
||||
case types.ApigwRouteResourceType:
|
||||
return map[string]bool{
|
||||
"read": true,
|
||||
@@ -949,8 +880,6 @@ func rbacResourceOperations(r string) map[string]bool {
|
||||
"queues.search": true,
|
||||
"apigw-route.create": true,
|
||||
"apigw-routes.search": true,
|
||||
"apigw-filter.create": true,
|
||||
"apigw-filters.search": true,
|
||||
"resource-translations.manage": true,
|
||||
}
|
||||
}
|
||||
@@ -958,50 +887,6 @@ func rbacResourceOperations(r string) map[string]bool {
|
||||
return nil
|
||||
}
|
||||
|
||||
// rbacApigwFilterResourceValidator checks validity of rbac resource and operations
|
||||
//
|
||||
// Can be called without operations to check for validity of resource string only
|
||||
//
|
||||
// This function is auto-generated
|
||||
func rbacApigwFilterResourceValidator(r string, oo ...string) error {
|
||||
defOps := rbacResourceOperations(r)
|
||||
for _, o := range oo {
|
||||
if !defOps[o] {
|
||||
return fmt.Errorf("invalid operation '%s' for system ApigwFilter resource", o)
|
||||
}
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(r, types.ApigwFilterResourceType) {
|
||||
// expecting resource to always include path
|
||||
return fmt.Errorf("invalid resource type")
|
||||
}
|
||||
|
||||
const sep = "/"
|
||||
var (
|
||||
pp = strings.Split(strings.Trim(r[len(types.ApigwFilterResourceType):], sep), sep)
|
||||
prc = []string{
|
||||
"ID",
|
||||
}
|
||||
)
|
||||
|
||||
if len(pp) != len(prc) {
|
||||
return fmt.Errorf("invalid resource path structure")
|
||||
}
|
||||
|
||||
for i := 0; i < len(pp); i++ {
|
||||
if pp[i] != "*" {
|
||||
if i > 0 && pp[i-1] == "*" {
|
||||
return fmt.Errorf("invalid resource path wildcard level (%d) for ApigwFilter", i)
|
||||
}
|
||||
|
||||
if _, err := cast.ToUint64E(pp[i]); err != nil {
|
||||
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// rbacApigwRouteResourceValidator checks validity of rbac resource and operations
|
||||
//
|
||||
// Can be called without operations to check for validity of resource string only
|
||||
|
||||
@@ -15,49 +15,46 @@ type (
|
||||
apigwFilter struct {
|
||||
actionlog actionlog.Recorder
|
||||
store store.Storer
|
||||
ac functionAccessController
|
||||
ac routeAccessController
|
||||
route *apigwRoute
|
||||
}
|
||||
|
||||
functionAccessController interface {
|
||||
CanSearchApigwFilters(context.Context) bool
|
||||
|
||||
CanCreateApigwFilter(context.Context) bool
|
||||
CanReadApigwFilter(context.Context, *types.ApigwFilter) bool
|
||||
CanUpdateApigwFilter(context.Context, *types.ApigwFilter) bool
|
||||
CanDeleteApigwFilter(context.Context, *types.ApigwFilter) bool
|
||||
}
|
||||
)
|
||||
|
||||
func Filter() *apigwFilter {
|
||||
return (&apigwFilter{
|
||||
return &apigwFilter{
|
||||
route: DefaultApigwRoute,
|
||||
ac: DefaultAccessControl,
|
||||
actionlog: DefaultActionlog,
|
||||
store: DefaultStore,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *apigwFilter) FindByID(ctx context.Context, ID uint64) (q *types.ApigwFilter, err error) {
|
||||
func (svc *apigwFilter) FindByID(ctx context.Context, filterID uint64) (q *types.ApigwFilter, err error) {
|
||||
var (
|
||||
rProps = &apigwFilterActionProps{}
|
||||
r *types.ApigwRoute
|
||||
)
|
||||
|
||||
err = func() error {
|
||||
if ID == 0 {
|
||||
if filterID == 0 {
|
||||
return ApigwFilterErrInvalidID()
|
||||
}
|
||||
|
||||
if !svc.ac.CanSearchApigwFilters(ctx) {
|
||||
return ApigwFilterErrNotAllowedToRead(rProps)
|
||||
}
|
||||
|
||||
if q, err = store.LookupApigwFilterByID(ctx, svc.store, ID); err != nil {
|
||||
if q, err = store.LookupApigwFilterByID(ctx, svc.store, filterID); err != nil {
|
||||
return TemplateErrInvalidID().Wrap(err)
|
||||
}
|
||||
|
||||
rProps.setFilter(q)
|
||||
|
||||
// Get route
|
||||
if r, err = svc.route.FindByID(ctx, q.Route); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !svc.ac.CanReadApigwRoute(ctx, r) {
|
||||
return ApigwRouteErrNotAllowedToRead()
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
@@ -71,17 +68,17 @@ func (svc *apigwFilter) Create(ctx context.Context, new *types.ApigwFilter) (q *
|
||||
)
|
||||
|
||||
err = func() (err error) {
|
||||
if !svc.ac.CanCreateApigwFilter(ctx) {
|
||||
return ApigwFilterErrNotAllowedToCreate(qProps)
|
||||
}
|
||||
|
||||
// Set new values after beforeCreate events are emitted
|
||||
new.ID = nextID()
|
||||
new.CreatedAt = *now()
|
||||
new.CreatedBy = a.GetIdentityFromContext(ctx).Identity()
|
||||
|
||||
if r, err = svc.route.FindByID(ctx, new.Route); err != nil {
|
||||
return ApigwFilterErrNotFound(qProps)
|
||||
if r, err = store.LookupApigwRouteByID(ctx, svc.store, new.Route); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.ac.CanUpdateApigwRoute(ctx, r) {
|
||||
return ApigwRouteErrNotAllowedToUpdate()
|
||||
}
|
||||
|
||||
// check for existing filters if route is async
|
||||
@@ -148,14 +145,14 @@ func (svc *apigwFilter) Update(ctx context.Context, upd *types.ApigwFilter) (q *
|
||||
return ApigwFilterErrNotFound(qProps)
|
||||
}
|
||||
|
||||
if !svc.ac.CanUpdateApigwFilter(ctx, qq) {
|
||||
return ApigwFilterErrNotAllowedToUpdate(qProps)
|
||||
}
|
||||
|
||||
if r, err = svc.route.FindByID(ctx, upd.Route); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !svc.ac.CanUpdateApigwRoute(ctx, r) {
|
||||
return ApigwRouteErrNotAllowedToUpdate()
|
||||
}
|
||||
|
||||
if qq, e = store.LookupApigwFilterByID(ctx, svc.store, upd.ID); e == nil && qq == nil {
|
||||
return ApigwFilterErrNotFound(qProps)
|
||||
}
|
||||
@@ -193,12 +190,14 @@ func (svc *apigwFilter) DeleteByID(ctx context.Context, ID uint64) (err error) {
|
||||
return ApigwFilterErrNotFound(qProps)
|
||||
}
|
||||
|
||||
if !svc.ac.CanDeleteApigwFilter(ctx, q) {
|
||||
return ApigwFilterErrNotAllowedToDelete(qProps)
|
||||
if r, err = store.LookupApigwRouteByID(ctx, svc.store, q.Route); err == store.ErrNotFound {
|
||||
return ApigwRouteErrNotFound()
|
||||
} else if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if r, err = svc.route.FindByID(ctx, q.Route); err != nil {
|
||||
return err
|
||||
if !svc.ac.CanDeleteApigwRoute(ctx, r) {
|
||||
return ApigwRouteErrNotAllowedToDelete()
|
||||
}
|
||||
|
||||
qProps.setFilter(q)
|
||||
@@ -233,12 +232,14 @@ func (svc *apigwFilter) UndeleteByID(ctx context.Context, ID uint64) (err error)
|
||||
return ApigwFilterErrNotFound(qProps)
|
||||
}
|
||||
|
||||
if !svc.ac.CanDeleteApigwFilter(ctx, q) {
|
||||
return ApigwFilterErrNotAllowedToDelete(qProps)
|
||||
if r, err = store.LookupApigwRouteByID(ctx, svc.store, q.Route); err == store.ErrNotFound {
|
||||
return ApigwRouteErrNotFound()
|
||||
} else if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if r, err = svc.route.FindByID(ctx, q.Route); err != nil {
|
||||
return err
|
||||
if !svc.ac.CanDeleteApigwRoute(ctx, r) {
|
||||
return ApigwRouteErrNotAllowedToUndelete()
|
||||
}
|
||||
|
||||
qProps.setFilter(q)
|
||||
@@ -264,18 +265,32 @@ func (svc *apigwFilter) UndeleteByID(ctx context.Context, ID uint64) (err error)
|
||||
func (svc *apigwFilter) Search(ctx context.Context, filter types.ApigwFilterFilter) (r types.ApigwFilterSet, f types.ApigwFilterFilter, err error) {
|
||||
var (
|
||||
aProps = &apigwFilterActionProps{search: &filter}
|
||||
route *types.ApigwRoute
|
||||
)
|
||||
|
||||
// For each fetched item, store backend will check if it is valid or not
|
||||
filter.Check = func(res *types.ApigwFilter) (bool, error) {
|
||||
if !svc.ac.CanReadApigwFilter(ctx, res) {
|
||||
return false, nil
|
||||
err = func() error {
|
||||
// Preload the corresponding API GW route for access control
|
||||
if filter.RouteID == 0 {
|
||||
return ApigwRouteErrInvalidID()
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
if route, err = store.LookupApigwRouteByID(ctx, svc.store, filter.RouteID); err != nil {
|
||||
return ApigwRouteErrNotFound()
|
||||
}
|
||||
|
||||
err = func() error {
|
||||
if !svc.ac.CanReadApigwRoute(ctx, route) {
|
||||
return ApigwRouteErrNotAllowedToRead()
|
||||
}
|
||||
|
||||
// Prepare the filter checker so we can evaluate access to specific filters
|
||||
filter.Check = func(res *types.ApigwFilter) (bool, error) {
|
||||
if !svc.ac.CanReadApigwRoute(ctx, route) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Go!
|
||||
if r, f, err = store.SearchApigwFilters(ctx, svc.store, filter); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -292,10 +307,9 @@ func (svc *apigwFilter) DefFilter(ctx context.Context, kind string) (l interface
|
||||
)
|
||||
|
||||
err = func() error {
|
||||
if !svc.ac.CanSearchApigwFilters(ctx) {
|
||||
return ApigwFilterErrNotAllowedToRead(qProps)
|
||||
if !svc.ac.CanSearchApigwRoutes(ctx) {
|
||||
return ApigwRouteErrNotAllowedToRead()
|
||||
}
|
||||
|
||||
// get the definitions from registry
|
||||
l = apigw.Service().Funcs(kind)
|
||||
|
||||
@@ -312,10 +326,9 @@ func (svc *apigwFilter) DefProxyAuth(ctx context.Context) (l interface{}, err er
|
||||
)
|
||||
|
||||
err = func() error {
|
||||
if !svc.ac.CanSearchApigwFilters(ctx) {
|
||||
return ApigwFilterErrNotAllowedToRead(qProps)
|
||||
if !svc.ac.CanSearchApigwRoutes(ctx) {
|
||||
return ApigwRouteErrNotAllowedToRead()
|
||||
}
|
||||
|
||||
// get the definitions from registry
|
||||
l = apigw.Service().ProxyAuthDef()
|
||||
|
||||
|
||||
180
system/service/apigw_filter_actions.gen.go
generated
180
system/service/apigw_filter_actions.gen.go
generated
@@ -435,186 +435,6 @@ func ApigwFilterErrInvalidRoute(mm ...*apigwFilterActionProps) *errors.Error {
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwFilterErrNotAllowedToCreate returns "system:filter.notAllowedToCreate" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ApigwFilterErrNotAllowedToCreate(mm ...*apigwFilterActionProps) *errors.Error {
|
||||
var p = &apigwFilterActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to create a filter", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToCreate"),
|
||||
errors.Meta("resource", "system:filter"),
|
||||
|
||||
// action log entry; no formatting, it will be applied inside recordAction fn.
|
||||
errors.Meta(apigwFilterLogMetaKey{}, "failed to create a route; insufficient permissions"),
|
||||
errors.Meta(apigwFilterPropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "apigwFilter.errors.notAllowedToCreate"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwFilterErrNotAllowedToRead returns "system:filter.notAllowedToRead" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ApigwFilterErrNotAllowedToRead(mm ...*apigwFilterActionProps) *errors.Error {
|
||||
var p = &apigwFilterActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to read this filter", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToRead"),
|
||||
errors.Meta("resource", "system:filter"),
|
||||
|
||||
// action log entry; no formatting, it will be applied inside recordAction fn.
|
||||
errors.Meta(apigwFilterLogMetaKey{}, "failed to read {{filter}}; insufficient permissions"),
|
||||
errors.Meta(apigwFilterPropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "apigwFilter.errors.notAllowedToRead"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwFilterErrNotAllowedToUpdate returns "system:filter.notAllowedToUpdate" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ApigwFilterErrNotAllowedToUpdate(mm ...*apigwFilterActionProps) *errors.Error {
|
||||
var p = &apigwFilterActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to update this filter", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToUpdate"),
|
||||
errors.Meta("resource", "system:filter"),
|
||||
|
||||
// action log entry; no formatting, it will be applied inside recordAction fn.
|
||||
errors.Meta(apigwFilterLogMetaKey{}, "failed to update {{filter}}; insufficient permissions"),
|
||||
errors.Meta(apigwFilterPropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "apigwFilter.errors.notAllowedToUpdate"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwFilterErrNotAllowedToDelete returns "system:filter.notAllowedToDelete" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ApigwFilterErrNotAllowedToDelete(mm ...*apigwFilterActionProps) *errors.Error {
|
||||
var p = &apigwFilterActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to delete this filter", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToDelete"),
|
||||
errors.Meta("resource", "system:filter"),
|
||||
|
||||
// action log entry; no formatting, it will be applied inside recordAction fn.
|
||||
errors.Meta(apigwFilterLogMetaKey{}, "failed to delete {{filter}}; insufficient permissions"),
|
||||
errors.Meta(apigwFilterPropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "apigwFilter.errors.notAllowedToDelete"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwFilterErrNotAllowedToUndelete returns "system:filter.notAllowedToUndelete" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ApigwFilterErrNotAllowedToUndelete(mm ...*apigwFilterActionProps) *errors.Error {
|
||||
var p = &apigwFilterActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to undelete this filter", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToUndelete"),
|
||||
errors.Meta("resource", "system:filter"),
|
||||
|
||||
// action log entry; no formatting, it will be applied inside recordAction fn.
|
||||
errors.Meta(apigwFilterLogMetaKey{}, "failed to undelete {{filter}}; insufficient permissions"),
|
||||
errors.Meta(apigwFilterPropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "apigwFilter.errors.notAllowedToUndelete"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwFilterErrAsyncRouteTooManyProcessers returns "system:filter.asyncRouteTooManyProcessers" as *errors.Error
|
||||
//
|
||||
//
|
||||
|
||||
@@ -54,26 +54,6 @@ errors:
|
||||
message: "invalid route"
|
||||
severity: warning
|
||||
|
||||
- error: notAllowedToCreate
|
||||
message: "not allowed to create a filter"
|
||||
log: "failed to create a route; insufficient permissions"
|
||||
|
||||
- error: notAllowedToRead
|
||||
message: "not allowed to read this filter"
|
||||
log: "failed to read {{filter}}; insufficient permissions"
|
||||
|
||||
- error: notAllowedToUpdate
|
||||
message: "not allowed to update this filter"
|
||||
log: "failed to update {{filter}}; insufficient permissions"
|
||||
|
||||
- error: notAllowedToDelete
|
||||
message: "not allowed to delete this filter"
|
||||
log: "failed to delete {{filter}}; insufficient permissions"
|
||||
|
||||
- error: notAllowedToUndelete
|
||||
message: "not allowed to undelete this filter"
|
||||
log: "failed to undelete {{filter}}; insufficient permissions"
|
||||
|
||||
- error: asyncRouteTooManyProcessers
|
||||
message: "processer already exists for this async route"
|
||||
log: "failed to add {{filter}}; too many processers, async route"
|
||||
|
||||
@@ -30,11 +30,11 @@ type (
|
||||
)
|
||||
|
||||
func Route() *apigwRoute {
|
||||
return (&apigwRoute{
|
||||
return &apigwRoute{
|
||||
ac: DefaultAccessControl,
|
||||
actionlog: DefaultActionlog,
|
||||
store: DefaultStore,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *apigwRoute) FindByID(ctx context.Context, ID uint64) (q *types.ApigwRoute, err error) {
|
||||
@@ -47,10 +47,6 @@ func (svc *apigwRoute) FindByID(ctx context.Context, ID uint64) (q *types.ApigwR
|
||||
return ApigwRouteErrInvalidID()
|
||||
}
|
||||
|
||||
if !svc.ac.CanSearchApigwRoutes(ctx) {
|
||||
return ApigwRouteErrNotAllowedToRead(rProps)
|
||||
}
|
||||
|
||||
if q, err = store.LookupApigwRouteByID(ctx, svc.store, ID); err != nil {
|
||||
return ApigwRouteErrInvalidID().Wrap(err)
|
||||
}
|
||||
@@ -133,7 +129,9 @@ func (svc *apigwRoute) Update(ctx context.Context, upd *types.ApigwRoute) (q *ty
|
||||
q = upd
|
||||
|
||||
// send the signal to reload all route
|
||||
apigw.Service().Reload(ctx)
|
||||
if qq.Enabled != upd.Enabled {
|
||||
apigw.Service().Reload(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
@@ -170,7 +168,9 @@ func (svc *apigwRoute) DeleteByID(ctx context.Context, ID uint64) (err error) {
|
||||
}
|
||||
|
||||
// send the signal to reload all queues
|
||||
apigw.Service().Reload(ctx)
|
||||
if q.Enabled {
|
||||
apigw.Service().Reload(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
@@ -194,7 +194,7 @@ func (svc *apigwRoute) UndeleteByID(ctx context.Context, ID uint64) (err error)
|
||||
}
|
||||
|
||||
if !svc.ac.CanDeleteApigwRoute(ctx, q) {
|
||||
return ApigwRouteErrNotAllowedToDelete(qProps)
|
||||
return ApigwRouteErrNotAllowedToUndelete(qProps)
|
||||
}
|
||||
|
||||
qProps.setRoute(q)
|
||||
@@ -207,7 +207,9 @@ func (svc *apigwRoute) UndeleteByID(ctx context.Context, ID uint64) (err error)
|
||||
}
|
||||
|
||||
// send the signal to reload all queues
|
||||
apigw.Service().Reload(ctx)
|
||||
if q.Enabled {
|
||||
apigw.Service().Reload(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
@@ -230,6 +232,10 @@ func (svc *apigwRoute) Search(ctx context.Context, filter types.ApigwRouteFilter
|
||||
}
|
||||
|
||||
err = func() error {
|
||||
if !svc.ac.CanSearchApigwRoutes(ctx) {
|
||||
return ApigwRouteErrNotAllowedToSearch()
|
||||
}
|
||||
|
||||
if r, f, err = store.SearchApigwRoutes(ctx, svc.store, filter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
36
system/service/apigw_route_actions.gen.go
generated
36
system/service/apigw_route_actions.gen.go
generated
@@ -635,6 +635,42 @@ func ApigwRouteErrNotAllowedToRead(mm ...*apigwRouteActionProps) *errors.Error {
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwRouteErrNotAllowedToSearch returns "system:apigw-route.notAllowedToSearch" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ApigwRouteErrNotAllowedToSearch(mm ...*apigwRouteActionProps) *errors.Error {
|
||||
var p = &apigwRouteActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to list or search routes", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToSearch"),
|
||||
errors.Meta("resource", "system:apigw-route"),
|
||||
|
||||
// action log entry; no formatting, it will be applied inside recordAction fn.
|
||||
errors.Meta(apigwRouteLogMetaKey{}, "failed to search for routes; insufficient permissions"),
|
||||
errors.Meta(apigwRoutePropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "apigwRoute.errors.notAllowedToSearch"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ApigwRouteErrNotAllowedToUpdate returns "system:apigw-route.notAllowedToUpdate" as *errors.Error
|
||||
//
|
||||
//
|
||||
|
||||
@@ -76,6 +76,10 @@ errors:
|
||||
message: "not allowed to read this route"
|
||||
log: "failed to read {{route.endpoint}}; insufficient permissions"
|
||||
|
||||
- error: notAllowedToSearch
|
||||
message: "not allowed to list or search routes"
|
||||
log: "failed to search for routes; insufficient permissions"
|
||||
|
||||
- error: notAllowedToUpdate
|
||||
message: "not allowed to update this route"
|
||||
log: "failed to update {{route.endpoint}}; insufficient permissions"
|
||||
|
||||
@@ -29,10 +29,8 @@ type (
|
||||
}
|
||||
|
||||
ApigwFilterFilter struct {
|
||||
RouteID uint64 `json:"routeID,string"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Group string `json:"group"`
|
||||
Enabled bool `json:"enabled"`
|
||||
RouteID uint64 `json:"routeID,string"`
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
Deleted filter.State `json:"deleted"`
|
||||
|
||||
|
||||
33
system/types/rbac.gen.go
generated
33
system/types/rbac.gen.go
generated
@@ -7,7 +7,6 @@ package types
|
||||
//
|
||||
|
||||
// Definitions file that controls how this file is generated:
|
||||
// - system.apigw-filter.yaml
|
||||
// - system.apigw-route.yaml
|
||||
// - system.application.yaml
|
||||
// - system.auth-client.yaml
|
||||
@@ -30,7 +29,6 @@ type (
|
||||
)
|
||||
|
||||
const (
|
||||
ApigwFilterResourceType = "corteza::system:apigw-filter"
|
||||
ApigwRouteResourceType = "corteza::system:apigw-route"
|
||||
ApplicationResourceType = "corteza::system:application"
|
||||
AuthClientResourceType = "corteza::system:auth-client"
|
||||
@@ -41,37 +39,6 @@ const (
|
||||
ComponentResourceType = "corteza::system"
|
||||
)
|
||||
|
||||
// RbacResource returns string representation of RBAC resource for ApigwFilter by calling ApigwFilterRbacResource fn
|
||||
//
|
||||
// RBAC resource is in the corteza::system:apigw-filter/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (r ApigwFilter) RbacResource() string {
|
||||
return ApigwFilterRbacResource(r.ID)
|
||||
}
|
||||
|
||||
// ApigwFilterRbacResource returns string representation of RBAC resource for ApigwFilter
|
||||
//
|
||||
// RBAC resource is in the corteza::system:apigw-filter/... format
|
||||
//
|
||||
// This function is auto-generated
|
||||
func ApigwFilterRbacResource(id uint64) string {
|
||||
cpts := []interface{}{ApigwFilterResourceType}
|
||||
if id != 0 {
|
||||
cpts = append(cpts, strconv.FormatUint(id, 10))
|
||||
} else {
|
||||
cpts = append(cpts, "*")
|
||||
}
|
||||
|
||||
return fmt.Sprintf(ApigwFilterRbacResourceTpl(), cpts...)
|
||||
|
||||
}
|
||||
|
||||
// @todo template
|
||||
func ApigwFilterRbacResourceTpl() string {
|
||||
return "%s/%s"
|
||||
}
|
||||
|
||||
// RbacResource returns string representation of RBAC resource for ApigwRoute by calling ApigwRouteRbacResource fn
|
||||
//
|
||||
// RBAC resource is in the corteza::system:apigw-route/... format
|
||||
|
||||
504
tests/system/apigw_test.go
Normal file
504
tests/system/apigw_test.go
Normal file
@@ -0,0 +1,504 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/id"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"github.com/cortezaproject/corteza-server/system/service"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"github.com/cortezaproject/corteza-server/tests/helpers"
|
||||
jsonpath "github.com/steinfletcher/apitest-jsonpath"
|
||||
)
|
||||
|
||||
func (h helper) createRouteWithFilter(s string, fkind string) (*types.ApigwRoute, *types.ApigwFilter) {
|
||||
r := h.createRoute(&types.ApigwRoute{Endpoint: "/" + s, Method: "GET"})
|
||||
f := h.createFilters(&types.ApigwFilter{Kind: fkind}, r.ID)
|
||||
|
||||
return r, f
|
||||
}
|
||||
|
||||
func (h helper) createRoute(route *types.ApigwRoute) *types.ApigwRoute {
|
||||
if route.ID == 0 {
|
||||
route.ID = id.Next()
|
||||
}
|
||||
|
||||
if route.CreatedAt.IsZero() {
|
||||
route.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
h.a.NoError(service.DefaultStore.CreateApigwRoute(context.Background(), route))
|
||||
return route
|
||||
}
|
||||
|
||||
func (h helper) createFilters(f *types.ApigwFilter, routeID uint64) *types.ApigwFilter {
|
||||
f.Route = routeID
|
||||
|
||||
if f.ID == 0 {
|
||||
f.ID = id.Next()
|
||||
}
|
||||
|
||||
if f.CreatedAt.IsZero() {
|
||||
f.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
h.a.NoError(service.DefaultStore.CreateApigwFilter(context.Background(), f))
|
||||
return f
|
||||
}
|
||||
|
||||
func (h helper) clearRoutes() {
|
||||
h.noError(store.TruncateApigwFilters(context.Background(), service.DefaultStore))
|
||||
h.noError(store.TruncateApigwRoutes(context.Background(), service.DefaultStore))
|
||||
}
|
||||
|
||||
func TestApigwRouteRead(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/route/%d", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Equal(`$.response.routeID`, strconv.FormatUint(r.ID, 10))).
|
||||
Assert(jsonpath.Equal(`$.response.endpoint`, "/test")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteRead_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/route/%d", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToRead")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteSearch(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
h.createRouteWithFilter("test1", "")
|
||||
h.createRouteWithFilter("test2", "")
|
||||
|
||||
helpers.AllowMe(h, types.ComponentRbacResource(), "apigw-routes.search")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(0), "read")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/route/")).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response.set`, 2)).
|
||||
Assert(jsonpath.Equal(`$.response.set[0].endpoint`, "/test1")).
|
||||
Assert(jsonpath.Equal(`$.response.set[1].endpoint`, "/test2")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteSearch_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
h.createRouteWithFilter("test1", "")
|
||||
h.createRouteWithFilter("test2", "")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/route/")).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToSearch")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteSearch_forbidenSpecific(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test1", "")
|
||||
h.createRouteWithFilter("test2", "")
|
||||
|
||||
helpers.AllowMe(h, types.ComponentRbacResource(), "apigw-routes.search")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(0), "read")
|
||||
helpers.DenyMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/route/")).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response.set`, 1)).
|
||||
Assert(jsonpath.Equal(`$.response.set[0].endpoint`, "/test2")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteCreate(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
helpers.AllowMe(h, types.ComponentRbacResource(), "apigw-route.create")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/route")).
|
||||
Header("Accept", "application/json").
|
||||
FormData("endpoint", "/test").
|
||||
FormData("method", "GET").
|
||||
FormData("enabled", "false").
|
||||
FormData("group", "g1").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present(`$.response.routeID`)).
|
||||
Assert(jsonpath.Equal(`$.response.endpoint`, "/test")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteCreate_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/route")).
|
||||
Header("Accept", "application/json").
|
||||
FormData("endpoint", "/test").
|
||||
FormData("method", "GET").
|
||||
FormData("enabled", "false").
|
||||
FormData("group", "g1").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToCreate")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteUpdate(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "update")
|
||||
|
||||
h.apiInit().
|
||||
Put(fmt.Sprintf("/apigw/route/%d", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
FormData("endpoint", "/test-edited").
|
||||
FormData("enabled", "false").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present(`$.response.routeID`)).
|
||||
Assert(jsonpath.Equal(`$.response.endpoint`, "/test-edited")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteUpdate_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
h.apiInit().
|
||||
Put(fmt.Sprintf("/apigw/route/%d", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
FormData("endpoint", "/test-edited").
|
||||
FormData("enabled", "false").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToUpdate")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteDelete(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "delete")
|
||||
|
||||
h.apiInit().
|
||||
Delete(fmt.Sprintf("/apigw/route/%d", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteDelete_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
h.apiInit().
|
||||
Delete(fmt.Sprintf("/apigw/route/%d", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToDelete")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteUnDelete(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "delete")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/route/%d/undelete", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwRouteUnDelete_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test", "")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/route/%d/undelete", r.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToUndelete")).
|
||||
End()
|
||||
}
|
||||
|
||||
// Filters
|
||||
|
||||
func TestApigwFilterRead(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test", "test")
|
||||
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/filter/%d", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Equal(`$.response.filterID`, strconv.FormatUint(f.ID, 10))).
|
||||
Assert(jsonpath.Equal(`$.response.routeID`, strconv.FormatUint(r.ID, 10))).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterRead_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
_, f := h.createRouteWithFilter("test", "test")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/filter/%d", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToRead")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterSearch(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test1", "")
|
||||
|
||||
helpers.AllowMe(h, types.ComponentRbacResource(), "apigw-routes.search")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(0), "read")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/filter/")).
|
||||
Query("routeID", strconv.FormatUint(r.ID, 10)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response.set`, 1)).
|
||||
Assert(jsonpath.Equal(`$.response.set[0].filterID`, strconv.FormatUint(f.ID, 10))).
|
||||
Assert(jsonpath.Equal(`$.response.set[0].routeID`, strconv.FormatUint(r.ID, 10))).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterSearch_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test1", "")
|
||||
|
||||
h.apiInit().
|
||||
Get(fmt.Sprintf("/apigw/filter/")).
|
||||
Query("routeID", strconv.FormatUint(r.ID, 10)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToRead")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterCreate(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "update")
|
||||
|
||||
h.apiInit().
|
||||
Put(fmt.Sprintf("/apigw/filter")).
|
||||
Header("Accept", "application/json").
|
||||
FormData("routeID", strconv.FormatUint(r.ID, 10)).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Present(`$.response.filterID`)).
|
||||
Assert(jsonpath.Equal(`$.response.routeID`, strconv.FormatUint(r.ID, 10))).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterCreate_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, _ := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
|
||||
h.apiInit().
|
||||
Put(fmt.Sprintf("/apigw/filter")).
|
||||
Header("Accept", "application/json").
|
||||
FormData("routeID", strconv.FormatUint(r.ID, 10)).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToUpdate")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterUpdate(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "update")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/filter/%d", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
FormData("routeID", strconv.FormatUint(r.ID, 10)).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Equal(`$.response.filterID`, strconv.FormatUint(f.ID, 10))).
|
||||
Assert(jsonpath.Equal(`$.response.routeID`, strconv.FormatUint(r.ID, 10))).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterUpdate_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/filter/%d", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
FormData("routeID", strconv.FormatUint(r.ID, 10)).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToUpdate")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterDelete(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "delete")
|
||||
|
||||
h.apiInit().
|
||||
Delete(fmt.Sprintf("/apigw/filter/%d", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterDelete_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
_, f := h.createRouteWithFilter("test1", "")
|
||||
|
||||
h.apiInit().
|
||||
Delete(fmt.Sprintf("/apigw/filter/%d", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToDelete")).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterUnDelete(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "delete")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/filter/%d/undelete", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
}
|
||||
|
||||
func TestApigwFilterUnDelete_forbiden(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearRoutes()
|
||||
|
||||
r, f := h.createRouteWithFilter("test1", "")
|
||||
helpers.AllowMe(h, types.ApigwRouteRbacResource(r.ID), "read")
|
||||
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/apigw/filter/%d/undelete", f.ID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertError("apigwRoute.errors.notAllowedToUndelete")).
|
||||
End()
|
||||
}
|
||||
Reference in New Issue
Block a user