This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new b99eda5 Service Categories tenancy cross referencing DS tenancy
(#5146)
b99eda5 is described below
commit b99eda51b03505f48d67aadf481d16470455a7f4
Author: mattjackson220 <[email protected]>
AuthorDate: Tue Oct 27 16:09:39 2020 -0600
Service Categories tenancy cross referencing DS tenancy (#5146)
* Service Categories tenancy cross referencing DS tenancy
* update per comment
---
.../deliveryservice/deliveryservices.go | 44 ++++++++++++++++++++++
.../servicecategory/servicecategories.go | 31 +++++++++++++--
traffic_ops/traffic_ops_golang/tenant/tenancy.go | 35 +++++++++++++++--
.../FormDeliveryServiceController.js | 2 +-
4 files changed, 105 insertions(+), 7 deletions(-)
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
index 5bd05fd..fe7a665 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
@@ -194,6 +194,28 @@ func CreateV30(w http.ResponseWriter, r *http.Request) {
return
}
+ if ds.ServiceCategory != nil {
+ serviceCategoryTenantId, exists, err :=
tenant.GetServiceCategoryTenantIDByNameTx(inf.Tx.Tx, *ds.ServiceCategory)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx,
http.StatusInternalServerError, nil, errors.New("getting service category
tenancy"))
+ return
+ }
+ if !exists {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest,
errors.New("service category "+*ds.ServiceCategory+" does not exist"), nil)
+ return
+ }
+
+ ok, err := tenant.CrossReferenceTenancy(inf.Tx.Tx,
serviceCategoryTenantId, *ds.TenantID)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx,
http.StatusInternalServerError, nil, errors.New("cross referencing service
category tenancy with delivery service"))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest,
errors.New("delivery service tenant does not have access to this service
category"), nil)
+ return
+ }
+ }
+
res, status, userErr, sysErr := createV30(w, r, inf, ds)
if userErr != nil || sysErr != nil {
api.HandleErr(w, r, inf.Tx.Tx, status, userErr, sysErr)
@@ -607,6 +629,28 @@ func UpdateV30(w http.ResponseWriter, r *http.Request) {
}
ds.ID = &id
+ if ds.ServiceCategory != nil {
+ serviceCategoryTenantId, exists, err :=
tenant.GetServiceCategoryTenantIDByNameTx(inf.Tx.Tx, *ds.ServiceCategory)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx,
http.StatusInternalServerError, nil, errors.New("getting service category
tenancy"))
+ return
+ }
+ if !exists {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest,
errors.New("service category "+*ds.ServiceCategory+" does not exist"), nil)
+ return
+ }
+
+ ok, err := tenant.CrossReferenceTenancy(inf.Tx.Tx,
serviceCategoryTenantId, *ds.TenantID)
+ if err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx,
http.StatusInternalServerError, nil, errors.New("cross referencing service
category tenancy with delivery service"))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest,
errors.New("delivery service tenant does not have access to this service
category"), nil)
+ return
+ }
+ }
+
res, status, userErr, sysErr := updateV30(w, r, inf, &ds)
if userErr != nil || sysErr != nil {
api.HandleErr(w, r, inf.Tx.Tx, status, userErr, sysErr)
diff --git
a/traffic_ops/traffic_ops_golang/servicecategory/servicecategories.go
b/traffic_ops/traffic_ops_golang/servicecategory/servicecategories.go
index d585aee..41ef03f 100644
--- a/traffic_ops/traffic_ops_golang/servicecategory/servicecategories.go
+++ b/traffic_ops/traffic_ops_golang/servicecategory/servicecategories.go
@@ -136,12 +136,37 @@ func (serviceCategory *TOServiceCategory) Read(h
http.Header, useIMS bool) ([]in
filteredServiceCategories := []interface{}{}
for _, sc := range serviceCategories {
- sc1 := sc.(*tc.ServiceCategory)
- if checkTenancy(sc1, tenantIDs) {
- filteredServiceCategories =
append(filteredServiceCategories, sc1)
+ scToCheck := sc.(*tc.ServiceCategory)
+ if checkTenancy(scToCheck, tenantIDs) {
+ filteredServiceCategories =
append(filteredServiceCategories, scToCheck)
}
}
+ dsIdParam := serviceCategory.APIInfo().Params["dsId"]
+
+ if dsIdParam != "" {
+ dsId, err := strconv.Atoi(dsIdParam)
+ if err != nil {
+ return nil, errors.New("dsId query param must be an
int"), nil, http.StatusBadRequest, nil
+ }
+ dsTenantId, _, err :=
tenant.GetDSTenantIDByIDTx(serviceCategory.APIInfo().Tx.Tx, dsId)
+
+ dsAllowedTenants, err :=
tenant.GetUserTenantIDListTx(serviceCategory.APIInfo().Tx.Tx, *dsTenantId)
+ if err != nil {
+ return nil, nil, errors.New("getting tenant list for
user: " + err.Error()), http.StatusInternalServerError, nil
+ }
+
+ filteredSCByDS := []interface{}{}
+ for _, sc := range filteredServiceCategories {
+ scToCheck := sc.(*tc.ServiceCategory)
+ if checkTenancy(scToCheck, dsAllowedTenants) {
+ filteredSCByDS = append(filteredSCByDS,
scToCheck)
+ }
+ }
+
+ return filteredSCByDS, nil, nil, errCode, maxTime
+ }
+
return filteredServiceCategories, nil, nil, errCode, maxTime
}
diff --git a/traffic_ops/traffic_ops_golang/tenant/tenancy.go
b/traffic_ops/traffic_ops_golang/tenant/tenancy.go
index c40643c..e7827da 100644
--- a/traffic_ops/traffic_ops_golang/tenant/tenancy.go
+++ b/traffic_ops/traffic_ops_golang/tenant/tenancy.go
@@ -83,7 +83,7 @@ func Check(user *auth.CurrentUser, XMLID string, tx *sql.Tx)
(error, error, int)
// a system error, and an HTTP error code. If both the user and system error
are nil, the error
// code should be ignored.
func CheckID(tx *sql.Tx, user *auth.CurrentUser, dsID int) (error, error, int)
{
- dsTenantID, ok, err := getDSTenantIDByIDTx(tx, dsID)
+ dsTenantID, ok, err := GetDSTenantIDByIDTx(tx, dsID)
if err != nil {
return nil, errors.New("checking tenant: " + err.Error()),
http.StatusInternalServerError
}
@@ -214,10 +214,10 @@ FETCH FIRST 1 ROW ONLY;
}
}
-// getDSTenantIDByIDTx returns the tenant ID, whether the delivery service
exists, and any error.
+// GetDSTenantIDByIDTx returns the tenant ID, whether the delivery service
exists, and any error.
// Note the id may be nil, even if true is returned, if the delivery service
exists but its tenant_id field is null.
// TODO move somewhere generic
-func getDSTenantIDByIDTx(tx *sql.Tx, id int) (*int, bool, error) {
+func GetDSTenantIDByIDTx(tx *sql.Tx, id int) (*int, bool, error) {
tenantID := (*int)(nil)
if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where id =
$1`, id).Scan(&tenantID); err != nil {
if err == sql.ErrNoRows {
@@ -227,3 +227,32 @@ func getDSTenantIDByIDTx(tx *sql.Tx, id int) (*int, bool,
error) {
}
return tenantID, true, nil
}
+
+// GetServiceCategoryTenantIDByNameTx returns the tenant ID, whether the
service category exists, and any error.
+func GetServiceCategoryTenantIDByNameTx(tx *sql.Tx, name string) (int, bool,
error) {
+ var tenantID int
+ if err := tx.QueryRow(`SELECT tenant_id FROM service_category where
name = $1`, name).Scan(&tenantID); err != nil {
+ if err == sql.ErrNoRows {
+ return 0, false, nil
+ }
+ return 0, false, fmt.Errorf("querying tenant ID for service
category name '%v': %v", name, err)
+ }
+ return tenantID, true, nil
+}
+
+// CrossReferenceTenancy returns whether the tenantId is within the tenancy
tree hierarchy of the tenantIdToReference
+// and any error.
+func CrossReferenceTenancy(tx *sql.Tx, tenantId int, tenantIdToReference int)
(bool, error) {
+ allowedTenants, err := GetUserTenantIDListTx(tx, tenantIdToReference)
+ if err != nil {
+ return false, errors.New("getting tenant list: " + err.Error())
+ }
+
+ for _, tenantID := range allowedTenants {
+ if tenantID == tenantId {
+ return true, nil
+ }
+ }
+ return false, nil
+
+}
diff --git
a/traffic_portal/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
b/traffic_portal/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
index be36235..07f487a 100644
---
a/traffic_portal/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
+++
b/traffic_portal/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
@@ -47,7 +47,7 @@ var FormDeliveryServiceController = function(deliveryService,
dsCurrent, origin,
};
var getServiceCategories = function() {
- serviceCategoryService.getServiceCategories()
+ serviceCategoryService.getServiceCategories({dsId: deliveryService.id
})
.then(function(result) {
$scope.serviceCategories = result;
});