You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2019/04/19 23:25:57 UTC
[trafficcontrol] branch master updated: Fix code that checks the
use_tenancy parameter (#3311)
This is an automated email from the ASF dual-hosted git repository.
dangogh 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 b3226b2 Fix code that checks the use_tenancy parameter (#3311)
b3226b2 is described below
commit b3226b24538fd81aef57bce4f0c44dff755d1942
Author: Rawlin Peters <Ra...@gmail.com>
AuthorDate: Fri Apr 19 17:25:52 2019 -0600
Fix code that checks the use_tenancy parameter (#3311)
* Fix code that checks the use_tenancy parameter
Tenancy is always enabled, so we no longer have to check the use_tenancy
parameter. This should allow us to delete the use_tenancy parameter now.
* Add UserTenancyTest
* Add Origin tenancy API tests
* Add deliveryservices tenancy API tests
* Add tenancy deletion API tests
* Add TO API tests for creating resources outside of tenant boundaries
---
traffic_ops/app/lib/Utils/Tenant.pm | 15 +-
.../testing/api/v14/deliveryservices_test.go | 62 +++++++-
traffic_ops/testing/api/v14/origins_test.go | 67 ++++++++-
traffic_ops/testing/api/v14/user_test.go | 74 ++++++++++
traffic_ops/traffic_ops_golang/apitenant/tenant.go | 15 +-
.../deliveryservice/deliveryservicesv12.go | 4 -
.../deliveryservice/deliveryservicesv13.go | 15 +-
.../traffic_ops_golang/deliveryservice/eligible.go | 34 ++---
.../traffic_ops_golang/deliveryservice/matches.go | 14 +-
.../deliveryservice/request/requests.go | 12 +-
.../deliveryservice/servers/servers.go | 22 +--
.../traffic_ops_golang/deliveryservice/urlkey.go | 158 ++++++++-------------
traffic_ops/traffic_ops_golang/origin/origins.go | 77 ++++------
traffic_ops/traffic_ops_golang/tenant/tenancy.go | 85 +----------
14 files changed, 325 insertions(+), 329 deletions(-)
diff --git a/traffic_ops/app/lib/Utils/Tenant.pm b/traffic_ops/app/lib/Utils/Tenant.pm
index 0d2a69d..8259fa0 100644
--- a/traffic_ops/app/lib/Utils/Tenant.pm
+++ b/traffic_ops/app/lib/Utils/Tenant.pm
@@ -71,9 +71,8 @@ sub new {
# config_file => 'global', name => 'use_tenancy' } )
# ->get_column('value')->single();
- my $use_tenancy_value = $dbh->resultset("Parameter")->search( { config_file => 'global', name => 'use_tenancy' } )
- ->get_column('value')->single();
- my $use_tenancy = defined($use_tenancy_value) ? $use_tenancy_value != '0' : 0;
+ # tenancy is always enabled
+ my $use_tenancy = 1;
my $self = {
dbh => $dbh,
@@ -254,14 +253,8 @@ sub is_ds_resource_accessible_to_tenant {
}
sub use_tenancy {
- # With tenancy, the DS/User mapping is no longer required for isolation.
- # So we need a knob to turn of this mechanisem if/as-long it is not depraceted.
- my $self = shift;
- if ($self->{use_tenancy}) {
- #mechanisem disabled
- return 1;
- }
- return 0;
+ # tenancy is always enabled
+ return 1;
}
sub get_tenant_heirarchy_depth {
diff --git a/traffic_ops/testing/api/v14/deliveryservices_test.go b/traffic_ops/testing/api/v14/deliveryservices_test.go
index eec83e1..8af81a7 100644
--- a/traffic_ops/testing/api/v14/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v14/deliveryservices_test.go
@@ -18,15 +18,19 @@ package v14
import (
"strconv"
"testing"
+ "time"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+ toclient "github.com/apache/trafficcontrol/traffic_ops/client"
)
func TestDeliveryServices(t *testing.T) {
- WithObjs(t, []TCObj{CDNs, Types, Tenants, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, DeliveryServices}, func() {
+ WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, DeliveryServices}, func() {
UpdateTestDeliveryServices(t)
UpdateNullableTestDeliveryServices(t)
GetTestDeliveryServices(t)
+ DeliveryServiceTenancyTest(t)
})
}
@@ -169,7 +173,7 @@ func UpdateNullableTestDeliveryServices(t *testing.T) {
func DeleteTestDeliveryServices(t *testing.T) {
dses, _, err := TOSession.GetDeliveryServices()
if err != nil {
- t.Errorf("cannot GET Servers: %v\n", err)
+ t.Errorf("cannot GET deliveryservices: %v\n", err)
}
for _, testDS := range testData.DeliveryServices {
ds := tc.DeliveryService{}
@@ -206,3 +210,57 @@ func DeleteTestDeliveryServices(t *testing.T) {
}
}
}
+
+func DeliveryServiceTenancyTest(t *testing.T) {
+ dses, _, err := TOSession.GetDeliveryServicesNullable()
+ if err != nil {
+ t.Errorf("cannot GET deliveryservices: %v\n", err)
+ }
+ tenant3DS := tc.DeliveryServiceNullable{}
+ foundTenant3DS := false
+ for _, d := range dses {
+ if *d.XMLID == "ds3" {
+ tenant3DS = d
+ foundTenant3DS = true
+ }
+ }
+ if !foundTenant3DS || *tenant3DS.Tenant != "tenant3" {
+ t.Error("expected to find deliveryservice 'ds3' with tenant 'tenant3'")
+ }
+
+ toReqTimeout := time.Second * time.Duration(Config.Default.Session.TimeoutInSecs)
+ tenant4TOClient, _, err := toclient.LoginWithAgent(TOSession.URL, "tenant4user", "pa$$word", true, "to-api-v14-client-tests/tenant4user", true, toReqTimeout)
+ if err != nil {
+ t.Fatalf("failed to log in with tenant4user: %v", err.Error())
+ }
+
+ dsesReadableByTenant4, _, err := tenant4TOClient.GetDeliveryServicesNullable()
+ if err != nil {
+ t.Error("tenant4user cannot GET deliveryservices")
+ }
+
+ // assert that tenant4user cannot read deliveryservices outside of its tenant
+ for _, ds := range dsesReadableByTenant4 {
+ if *ds.XMLID == "ds3" {
+ t.Error("expected tenant4 to be unable to read delivery services from tenant 3")
+ }
+ }
+
+ // assert that tenant4user cannot update tenant3user's deliveryservice
+ if _, err = tenant4TOClient.UpdateDeliveryServiceNullable(string(*tenant3DS.ID), &tenant3DS); err == nil {
+ t.Errorf("expected tenant4user to be unable to update tenant3's deliveryservice (%s)", *tenant3DS.XMLID)
+ }
+
+ // assert that tenant4user cannot delete tenant3user's deliveryservice
+ if _, err = tenant4TOClient.DeleteDeliveryService(string(*tenant3DS.ID)); err == nil {
+ t.Errorf("expected tenant4user to be unable to delete tenant3's deliveryservice (%s)", *tenant3DS.XMLID)
+ }
+
+ // assert that tenant4user cannot create a deliveryservice outside of its tenant
+ tenant3DS.XMLID = util.StrPtr("deliveryservicetenancytest")
+ tenant3DS.DisplayName = util.StrPtr("deliveryservicetenancytest")
+ if _, err = tenant4TOClient.CreateDeliveryServiceNullable(&tenant3DS); err == nil {
+ t.Errorf("expected tenant4user to be unable to create a deliveryservice outside of its tenant")
+ }
+
+}
diff --git a/traffic_ops/testing/api/v14/origins_test.go b/traffic_ops/testing/api/v14/origins_test.go
index 32b454e..c31634c 100644
--- a/traffic_ops/testing/api/v14/origins_test.go
+++ b/traffic_ops/testing/api/v14/origins_test.go
@@ -17,12 +17,18 @@ package v14
import (
"testing"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+ toclient "github.com/apache/trafficcontrol/traffic_ops/client"
)
func TestOrigins(t *testing.T) {
- WithObjs(t, []TCObj{CDNs, Types, Tenants, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, DeliveryServices, Coordinates, Origins}, func() {
+ WithObjs(t, []TCObj{CDNs, Types, Tenants, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Users, DeliveryServices, Coordinates, Origins}, func() {
UpdateTestOrigins(t)
GetTestOrigins(t)
+ OriginTenancyTest(t)
})
}
@@ -37,8 +43,13 @@ func CreateTestOrigins(t *testing.T) {
}
func GetTestOrigins(t *testing.T) {
+ _, _, err := TOSession.GetOrigins()
+ if err != nil {
+ t.Errorf("cannot GET origins: %v\n", err)
+ }
+
for _, origin := range testData.Origins {
- resp, _, err := TOSession.GetServerByHostName(*origin.Name)
+ resp, _, err := TOSession.GetOriginByName(*origin.Name)
if err != nil {
t.Errorf("cannot GET Origin by name: %v - %v\n", err, resp)
}
@@ -79,6 +90,58 @@ func UpdateTestOrigins(t *testing.T) {
}
}
+func OriginTenancyTest(t *testing.T) {
+ origins, _, err := TOSession.GetOrigins()
+ if err != nil {
+ t.Errorf("cannot GET origins: %v\n", err)
+ }
+ tenant3Origin := tc.Origin{}
+ foundTenant3Origin := false
+ for _, o := range origins {
+ if *o.FQDN == "origin.ds3.example.net" {
+ tenant3Origin = o
+ foundTenant3Origin = true
+ }
+ }
+ if !foundTenant3Origin {
+ t.Error("expected to find origin with tenant 'tenant3' and fqdn 'origin.ds3.example.net'")
+ }
+
+ toReqTimeout := time.Second * time.Duration(Config.Default.Session.TimeoutInSecs)
+ tenant4TOClient, _, err := toclient.LoginWithAgent(TOSession.URL, "tenant4user", "pa$$word", true, "to-api-v14-client-tests/tenant4user", true, toReqTimeout)
+ if err != nil {
+ t.Fatalf("failed to log in with tenant4user: %v", err.Error())
+ }
+
+ originsReadableByTenant4, _, err := tenant4TOClient.GetOrigins()
+ if err != nil {
+ t.Error("tenant4user cannot GET origins")
+ }
+
+ // assert that tenant4user cannot read origins outside of its tenant
+ for _, origin := range originsReadableByTenant4 {
+ if *origin.FQDN == "origin.ds3.example.net" {
+ t.Error("expected tenant4 to be unable to read origins from tenant 3")
+ }
+ }
+
+ // assert that tenant4user cannot update tenant3user's origin
+ if _, _, err = tenant4TOClient.UpdateOriginByID(*tenant3Origin.ID, tenant3Origin); err == nil {
+ t.Error("expected tenant4user to be unable to update tenant3's origin")
+ }
+
+ // assert that tenant4user cannot delete an origin outside of its tenant
+ if _, _, err = tenant4TOClient.DeleteOriginByID(*origins[0].ID); err == nil {
+ t.Errorf("expected tenant4user to be unable to delete an origin outside of its tenant (origin %s)", *origins[0].Name)
+ }
+
+ // assert that tenant4user cannot create origins outside of its tenant
+ tenant3Origin.FQDN = util.StrPtr("origin.tenancy.test.example.com")
+ if _, _, err = tenant4TOClient.CreateOrigin(tenant3Origin); err == nil {
+ t.Errorf("expected tenant4user to be unable to create an origin outside of its tenant")
+ }
+}
+
func DeleteTestOrigins(t *testing.T) {
for _, origin := range testData.Origins {
resp, _, err := TOSession.GetOriginByName(*origin.Name)
diff --git a/traffic_ops/testing/api/v14/user_test.go b/traffic_ops/testing/api/v14/user_test.go
index dbb18ca..333054c 100644
--- a/traffic_ops/testing/api/v14/user_test.go
+++ b/traffic_ops/testing/api/v14/user_test.go
@@ -24,6 +24,7 @@ import (
"github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
toclient "github.com/apache/trafficcontrol/traffic_ops/client"
)
@@ -36,6 +37,7 @@ func TestUsers(t *testing.T) {
UserUpdateOwnRoleTest(t)
GetTestUsers(t)
GetTestUserCurrent(t)
+ UserTenancyTest(t)
})
}
@@ -238,6 +240,78 @@ func GetTestUserCurrent(t *testing.T) {
}
}
+func UserTenancyTest(t *testing.T) {
+ users, _, err := TOSession.GetUsers()
+ if err != nil {
+ t.Errorf("cannot GET users: %v\n", err)
+ }
+ tenant3Found := false
+ tenant4Found := false
+ tenant3Username := "tenant3user"
+ tenant4Username := "tenant4user"
+ tenant3User := tc.User{}
+
+ // assert admin user can view tenant3user and tenant4user
+ for _, user := range users {
+ if *user.Username == tenant3Username {
+ tenant3Found = true
+ tenant3User = user
+ } else if *user.Username == tenant4Username {
+ tenant4Found = true
+ }
+ if tenant3Found && tenant4Found {
+ break
+ }
+ }
+ if !tenant3Found || !tenant4Found {
+ t.Error("expected admin to be able to view tenants: tenant3 and tenant4")
+ }
+
+ toReqTimeout := time.Second * time.Duration(Config.Default.Session.TimeoutInSecs)
+ tenant4TOClient, _, err := toclient.LoginWithAgent(TOSession.URL, "tenant4user", "pa$$word", true, "to-api-v14-client-tests/tenant4user", true, toReqTimeout)
+ if err != nil {
+ t.Fatalf("failed to log in with tenant4user: %v", err.Error())
+ }
+
+ usersReadableByTenant4, _, err := tenant4TOClient.GetUsers()
+ if err != nil {
+ t.Error("tenant4user cannot GET users")
+ }
+
+ tenant4canReadItself := false
+ for _, user := range usersReadableByTenant4 {
+ // assert that tenant4user cannot read tenant3user
+ if *user.Username == tenant3Username {
+ t.Error("expected tenant4user to be unable to read tenant3user")
+ }
+ // assert that tenant4user can read itself
+ if *user.Username == tenant4Username {
+ tenant4canReadItself = true
+ }
+ }
+ if !tenant4canReadItself {
+ t.Error("expected tenant4user to be able to read itself")
+ }
+
+ // assert that tenant4user cannot update tenant3user
+ if _, _, err = tenant4TOClient.UpdateUserByID(*tenant3User.ID, &tenant3User); err == nil {
+ t.Error("expected tenant4user to be unable to update tenant4user")
+ }
+
+ // assert that tenant4user cannot create a user outside of its tenant
+ rootTenant, _, err := TOSession.TenantByName("root")
+ if err != nil {
+ t.Error("expected to be able to GET the root tenant")
+ }
+ newUser := testData.Users[0]
+ newUser.Email = util.StrPtr("testusertenancy@example.com")
+ newUser.Username = util.StrPtr("testusertenancy")
+ newUser.TenantID = &rootTenant.ID
+ if _, _, err = tenant4TOClient.CreateUser(&newUser); err == nil {
+ t.Error("expected tenant4user to be unable to create a new user in the root tenant")
+ }
+}
+
// ForceDeleteTestUsers forcibly deletes the users from the db.
func ForceDeleteTestUsers(t *testing.T) {
diff --git a/traffic_ops/traffic_ops_golang/apitenant/tenant.go b/traffic_ops/traffic_ops_golang/apitenant/tenant.go
index b901ca9..6187c4e 100644
--- a/traffic_ops/traffic_ops_golang/apitenant/tenant.go
+++ b/traffic_ops/traffic_ops_golang/apitenant/tenant.go
@@ -124,20 +124,7 @@ func (tn *TOTenant) Create() (error, error, int) { return api.GenericCreate(tn)
func (ten *TOTenant) Read() ([]interface{}, error, error, int) {
if ten.APIInfo().User.TenantID == auth.TenantIDInvalid {
- // NOTE: work around issue where user has no tenancy assigned. If tenancy turned off, there
- // should be no tenancy restrictions. This should be removed once tenant_id NOT NULL constraints
- // are in place
- enabled, err := tenant.IsTenancyEnabledTx(ten.APIInfo().Tx.Tx)
- if err != nil {
- return nil, nil, errors.New("tenant checking tenancy: " + err.Error()), http.StatusInternalServerError
- }
-
- if enabled {
- // tenancy enabled, but user doesn't belong to one -- return empty list
- return nil, nil, nil, http.StatusOK
- }
- // give it the root tenant -- since tenancy turned off, does not matter what it is
- ten.APIInfo().User.TenantID = 1
+ return nil, nil, nil, http.StatusOK
}
tenants, userErr, sysErr, errCode := api.GenericRead(ten)
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index ad112da..b9d03fb 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -73,7 +73,6 @@ func (ds *TODeliveryServiceV12) GetType() string {
}
// getDSTenantIDByID 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.
func getDSTenantIDByID(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 {
@@ -86,7 +85,6 @@ func getDSTenantIDByID(tx *sql.Tx, id int) (*int, bool, 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.
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 {
@@ -99,7 +97,6 @@ func GetDSTenantIDByIDTx(tx *sql.Tx, id int) (*int, bool, error) {
}
// getDSTenantIDByName 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.
func getDSTenantIDByName(tx *sql.Tx, name string) (*int, bool, error) {
tenantID := (*int)(nil)
if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where xml_id = $1`, name).Scan(&tenantID); err != nil {
@@ -112,7 +109,6 @@ func getDSTenantIDByName(tx *sql.Tx, name string) (*int, bool, error) {
}
// GetDSTenantIDByNameTx 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.
func GetDSTenantIDByNameTx(tx *sql.Tx, ds tc.DeliveryServiceName) (*int, bool, error) {
tenantID := (*int)(nil)
if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where xml_id = $1`, ds).Scan(&tenantID); err != nil {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
index e81a980..9d5759b 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
@@ -560,21 +560,12 @@ func readGetDeliveryServices(params map[string]string, tx *sqlx.Tx, user *auth.C
return nil, errs, tc.DataConflictError
}
- tenancyEnabled, err := tenant.IsTenancyEnabledTx(tx.Tx)
+ tenantIDs, err := tenant.GetUserTenantIDListTx(tx.Tx, user.TenantID)
if err != nil {
- log.Errorln("checking if tenancy is enabled: " + err.Error())
+ log.Errorln("received error querying for user's tenants: " + err.Error())
return nil, []error{tc.DBError}, tc.SystemError
}
-
- if tenancyEnabled {
- log.Debugln("Tenancy is enabled")
- tenantIDs, err := tenant.GetUserTenantIDListTx(tx.Tx, user.TenantID)
- if err != nil {
- log.Errorln("received error querying for user's tenants: " + err.Error())
- return nil, []error{tc.DBError}, tc.SystemError
- }
- where, queryValues = dbhelpers.AddTenancyCheck(where, queryValues, "ds.tenant_id", tenantIDs)
- }
+ where, queryValues = dbhelpers.AddTenancyCheck(where, queryValues, "ds.tenant_id", tenantIDs)
query := selectQuery() + where + orderBy
log.Debugln("generated deliveryServices query: " + query)
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go b/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
index 187ad10..dab511a 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
@@ -38,31 +38,21 @@ func GetServersEligible(w http.ResponseWriter, r *http.Request) {
}
defer inf.Close()
- // TODO create a helper function to check all this in a single line.
- ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+ dsTenantID, ok, err := GetDSTenantIDByIDTx(inf.Tx.Tx, inf.IntParams["id"])
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
return
}
- if ok {
- dsTenantID, ok, err := GetDSTenantIDByIDTx(inf.Tx.Tx, inf.IntParams["id"])
- if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- }
- if !ok {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
- return
- }
- if dsTenantID != nil {
- if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- } else if !authorized {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
- return
- }
- }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
}
servers, err := getEligibleServers(inf.Tx.Tx, inf.IntParams["id"])
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/matches.go b/traffic_ops/traffic_ops_golang/deliveryservice/matches.go
index ae9278d..516f19e 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/matches.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/matches.go
@@ -56,20 +56,14 @@ JOIN regex as r ON r.id = dsr.regex
WHERE ds.active = true
`
qParams := []interface{}{}
- tenancyEnabled, err := tenant.IsTenancyEnabledTx(tx)
+ tenantIDs, err := tenant.GetUserTenantIDListTx(tx, userTenantID)
if err != nil {
- return nil, errors.New("checking tenancy enabled: " + err.Error())
+ return nil, errors.New("getting user tenant ID list: " + err.Error())
}
- if tenancyEnabled {
- tenantIDs, err := tenant.GetUserTenantIDListTx(tx, userTenantID)
- if err != nil {
- return nil, errors.New("getting user tenant ID list: " + err.Error())
- }
- q += `
+ q += `
AND ds.tenant_id = ANY($1)
`
- qParams = append(qParams, pq.Array(tenantIDs))
- }
+ qParams = append(qParams, pq.Array(tenantIDs))
q += `
ORDER BY dsr.set_number
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/request/requests.go b/traffic_ops/traffic_ops_golang/deliveryservice/request/requests.go
index c0a6e1b..6dc738b 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/request/requests.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/request/requests.go
@@ -102,17 +102,11 @@ func (req *TODeliveryServiceRequest) Read() ([]interface{}, error, error, int) {
if len(errs) > 0 {
return nil, util.JoinErrs(errs), nil, http.StatusBadRequest
}
- tenancyEnabled, err := tenant.IsTenancyEnabledTx(req.APIInfo().Tx.Tx)
+ tenantIDs, err := tenant.GetUserTenantIDListTx(req.APIInfo().Tx.Tx, req.APIInfo().User.TenantID)
if err != nil {
- return nil, nil, errors.New("dsr checking tenancy enabled: " + err.Error()), http.StatusInternalServerError
- }
- if tenancyEnabled {
- tenantIDs, err := tenant.GetUserTenantIDListTx(req.APIInfo().Tx.Tx, req.APIInfo().User.TenantID)
- if err != nil {
- return nil, nil, errors.New("dsr getting tenant list: " + err.Error()), http.StatusInternalServerError
- }
- where, queryValues = dbhelpers.AddTenancyCheck(where, queryValues, "CAST(r.deliveryservice->>'tenantId' AS bigint)", tenantIDs)
+ return nil, nil, errors.New("dsr getting tenant list: " + err.Error()), http.StatusInternalServerError
}
+ where, queryValues = dbhelpers.AddTenancyCheck(where, queryValues, "CAST(r.deliveryservice->>'tenantId' AS bigint)", tenantIDs)
query := selectDeliveryServiceRequestsQuery() + where + orderBy
log.Debugln("Query is ", query)
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index 2a508ab..855a3a0 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -140,21 +140,15 @@ func (dss *TODeliveryServiceServer) readDSS(tx *sqlx.Tx, user *auth.CurrentUser,
orderby = "deliveryService"
}
- tenancyEnabled, err := tenant.IsTenancyEnabledTx(tx.Tx)
+ tenantIDs, err := tenant.GetUserTenantIDListTx(tx.Tx, user.TenantID)
if err != nil {
- return nil, errors.New("checking if tenancy is enabled: " + err.Error())
+ return nil, errors.New("getting user tenant ID list: " + err.Error())
}
- if tenancyEnabled {
- tenantIDs, err := tenant.GetUserTenantIDListTx(tx.Tx, user.TenantID)
- if err != nil {
- return nil, errors.New("getting user tenant ID list: " + err.Error())
- }
- for _, id := range tenantIDs {
- dss.TenantIDs = append(dss.TenantIDs, int64(id))
- }
+ for _, id := range tenantIDs {
+ dss.TenantIDs = append(dss.TenantIDs, int64(id))
}
- query, err := selectQuery(orderby, strconv.Itoa(limit), strconv.Itoa(offset), tenancyEnabled)
+ query, err := selectQuery(orderby, strconv.Itoa(limit), strconv.Itoa(offset))
if err != nil {
return nil, errors.New("creating query for DeliveryserviceServers: " + err.Error())
}
@@ -176,7 +170,7 @@ func (dss *TODeliveryServiceServer) readDSS(tx *sqlx.Tx, user *auth.CurrentUser,
return &tc.DeliveryServiceServerResponse{orderby, servers, page, limit}, nil
}
-func selectQuery(orderBy string, limit string, offset string, useTenancy bool) (string, error) {
+func selectQuery(orderBy string, limit string, offset string) (string, error) {
selectStmt := `SELECT
s.deliveryService,
s.server,
@@ -198,12 +192,10 @@ func selectQuery(orderBy string, limit string, offset string, useTenancy bool) (
}
// TODO refactor to use dbhelpers.AddTenancyCheck
- if useTenancy {
- selectStmt += `
+ selectStmt += `
JOIN deliveryservice d on s.deliveryservice = d.id
WHERE d.tenant_id = ANY(CAST(:accessibleTenants AS bigint[]))
`
- }
if orderBy != "" {
selectStmt += ` ORDER BY ` + orderBy
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
index e4f4a3f..26facf9 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/urlkey.go
@@ -57,31 +57,21 @@ func GetURLKeysByID(w http.ResponseWriter, r *http.Request) {
return
}
- // TODO create a helper function to check all this in a single line.
- ok, err = tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+ dsTenantID, ok, err := GetDSTenantIDByIDTx(inf.Tx.Tx, inf.IntParams["id"])
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
return
}
- if ok {
- dsTenantID, ok, err := GetDSTenantIDByIDTx(inf.Tx.Tx, inf.IntParams["id"])
- if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- }
- if !ok {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
- return
- }
- if dsTenantID != nil {
- if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- } else if !authorized {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
- return
- }
- }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
}
keys, ok, err := riaksvc.GetURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, inf.Config.RiakPort, ds)
@@ -111,31 +101,21 @@ func GetURLKeysByName(w http.ResponseWriter, r *http.Request) {
ds := tc.DeliveryServiceName(inf.Params["name"])
- // TODO create a helper function to check all this in a single line.
- ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+ dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
return
}
- if ok {
- dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
- if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- }
- if !ok {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
- return
- }
- if dsTenantID != nil {
- if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- } else if !authorized {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
- return
- }
- }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
}
keys, ok, err := riaksvc.GetURLSigKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, inf.Config.RiakPort, ds)
@@ -166,14 +146,25 @@ func CopyURLKeys(w http.ResponseWriter, r *http.Request) {
ds := tc.DeliveryServiceName(inf.Params["name"])
copyDS := tc.DeliveryServiceName(inf.Params["copy-name"])
- // TODO create a helper function to check all this in a single line.
- ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+ dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
return
}
- if ok {
- dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
+
+ {
+ copyDSTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, copyDS)
if err != nil {
api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
return
@@ -182,35 +173,12 @@ func CopyURLKeys(w http.ResponseWriter, r *http.Request) {
api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
return
}
- if dsTenantID != nil {
- if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- } else if !authorized {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
- return
- }
- }
-
- {
- copyDSTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, copyDS)
- if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- }
- if !ok {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
- return
- }
- if copyDSTenantID != nil {
- if authorized, err := tenant.IsResourceAuthorizedToUserTx(*copyDSTenantID, inf.User, inf.Tx.Tx); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- } else if !authorized {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this copy tenant"), nil)
- return
- }
- }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*copyDSTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this copy tenant"), nil)
+ return
}
}
@@ -246,31 +214,21 @@ func GenerateURLKeys(w http.ResponseWriter, r *http.Request) {
ds := tc.DeliveryServiceName(inf.Params["name"])
- // TODO create a helper function to check all this in a single line.
- ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+ dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
return
}
- if ok {
- dsTenantID, ok, err := GetDSTenantIDByNameTx(inf.Tx.Tx, ds)
- if err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- }
- if !ok {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
- return
- }
- if dsTenantID != nil {
- if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
- return
- } else if !authorized {
- api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
- return
- }
- }
+ if !ok {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusNotFound, errors.New("delivery service "+string(ds)+" not found"), nil)
+ return
+ }
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, inf.Tx.Tx, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
}
keys, err := GenerateURLSigKeys()
diff --git a/traffic_ops/traffic_ops_golang/origin/origins.go b/traffic_ops/traffic_ops_golang/origin/origins.go
index 9f16e73..d11deb7 100644
--- a/traffic_ops/traffic_ops_golang/origin/origins.go
+++ b/traffic_ops/traffic_ops_golang/origin/origins.go
@@ -103,35 +103,30 @@ func (origin *TOOrigin) Validate() error {
return util.JoinErrs(tovalidate.ToErrors(validateErrs))
}
-// GetTenantID returns a pointer to the Origin's tenant ID from the Tx and any error encountered
-func (origin *TOOrigin) GetTenantID(tx *sqlx.Tx) (*int, error) {
+// GetTenantID returns a pointer to the Origin's tenant ID from the Tx, whether or not the Origin exists, and any error encountered
+func (origin *TOOrigin) GetTenantID(tx *sqlx.Tx) (*int, bool, error) {
if origin.ID != nil {
var tenantID *int
if err := tx.QueryRow(`SELECT tenant FROM origin where id = $1`, *origin.ID).Scan(&tenantID); err != nil {
if err == sql.ErrNoRows {
- return nil, nil
+ return nil, false, nil
}
- return nil, fmt.Errorf("querying tenant ID for origin ID '%v': %v", *origin.ID, err)
+ return nil, false, fmt.Errorf("querying tenant ID for origin ID '%v': %v", *origin.ID, err)
}
- return tenantID, nil
+ return tenantID, true, nil
}
- return nil, nil
+ return nil, false, nil
}
func (origin *TOOrigin) IsTenantAuthorized(user *auth.CurrentUser) (bool, error) {
- currentTenantID, err := origin.GetTenantID(origin.ReqInfo.Tx)
- if err != nil {
- return false, err
+ currentTenantID, originExists, err := origin.GetTenantID(origin.ReqInfo.Tx)
+ if !originExists {
+ return true, nil
}
- tenancyEnabled, err := tenant.IsTenancyEnabledTx(origin.ReqInfo.Tx.Tx)
if err != nil {
return false, err
}
- if currentTenantID != nil && tenancyEnabled {
- return tenant.IsResourceAuthorizedToUserTx(*currentTenantID, user, origin.ReqInfo.Tx.Tx)
- }
-
- return true, nil
+ return tenant.IsResourceAuthorizedToUserTx(*currentTenantID, user, origin.ReqInfo.Tx.Tx)
}
func (origin *TOOrigin) Read() ([]interface{}, error, error, int) {
@@ -235,41 +230,31 @@ LEFT JOIN tenant t ON o.tenant = t.id`
}
func checkTenancy(originTenantID, deliveryserviceID *int, tx *sqlx.Tx, user *auth.CurrentUser) (error, tc.ApiErrorType) {
- tenancyEnabled, err := tenant.IsTenancyEnabledTx(tx.Tx)
+ if originTenantID == nil {
+ return tc.NilTenantError, tc.ForbiddenError
+ }
+ authorized, err := tenant.IsResourceAuthorizedToUserTx(*originTenantID, user, tx.Tx)
if err != nil {
- return errors.New("Error checking if tenancy enabled."), tc.SystemError
+ return err, tc.SystemError
+ }
+ if !authorized {
+ return tc.TenantUserNotAuthError, tc.ForbiddenError
}
- if tenancyEnabled {
- if originTenantID == nil {
- return tc.NilTenantError, tc.ForbiddenError
- }
- authorized, err := tenant.IsResourceAuthorizedToUserTx(*originTenantID, user, tx.Tx)
- if err != nil {
- return err, tc.SystemError
- }
- if !authorized {
- return tc.TenantUserNotAuthError, tc.ForbiddenError
- }
- if deliveryserviceID != nil {
- var deliveryserviceTenantID *int
- if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where id = $1`, *deliveryserviceID).Scan(&deliveryserviceTenantID); err != nil {
- if err == sql.ErrNoRows {
- return errors.New("checking tenancy: requested delivery service does not exist"), tc.DataConflictError
- }
- log.Errorf("could not get tenant_id from deliveryservice %d: %++v\n", *deliveryserviceID, err)
- return err, tc.SystemError
- }
- if deliveryserviceTenantID != nil {
- authorized, err := tenant.IsResourceAuthorizedToUserTx(*deliveryserviceTenantID, user, tx.Tx)
- if err != nil {
- return err, tc.SystemError
- }
- if !authorized {
- return tc.TenantDSUserNotAuthError, tc.ForbiddenError
- }
- }
+ var deliveryserviceTenantID int
+ if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where id = $1`, *deliveryserviceID).Scan(&deliveryserviceTenantID); err != nil {
+ if err == sql.ErrNoRows {
+ return errors.New("checking tenancy: requested delivery service does not exist"), tc.DataConflictError
}
+ log.Errorf("could not get tenant_id from deliveryservice %d: %++v\n", *deliveryserviceID, err)
+ return err, tc.SystemError
+ }
+ authorized, err = tenant.IsResourceAuthorizedToUserTx(deliveryserviceTenantID, user, tx.Tx)
+ if err != nil {
+ return err, tc.SystemError
+ }
+ if !authorized {
+ return tc.TenantDSUserNotAuthError, tc.ForbiddenError
}
return nil, tc.NoError
}
diff --git a/traffic_ops/traffic_ops_golang/tenant/tenancy.go b/traffic_ops/traffic_ops_golang/tenant/tenancy.go
index 4aee850..e600c37 100644
--- a/traffic_ops/traffic_ops_golang/tenant/tenancy.go
+++ b/traffic_ops/traffic_ops_golang/tenant/tenancy.go
@@ -81,14 +81,6 @@ func Check(user *auth.CurrentUser, XMLID string, tx *sql.Tx) (error, error, int)
// CheckID checks that the given user has access to the given delivery service. Returns a user error, 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) {
- ok, err := IsTenancyEnabledTx(tx)
- if err != nil {
- return nil, errors.New("checking tenancy enabled: " + err.Error()), http.StatusInternalServerError
- }
- if !ok {
- return nil, nil, http.StatusOK
- }
-
dsTenantID, ok, err := getDSTenantIDByIDTx(tx, dsID)
if err != nil {
return nil, errors.New("checking tenant: " + err.Error()), http.StatusInternalServerError
@@ -111,9 +103,6 @@ func CheckID(tx *sql.Tx, user *auth.CurrentUser, dsID int) (error, error, int) {
}
// GetUserTenantListTx returns a Tenant list that the specified user has access to.
-// NOTE: This method does not use the use_tenancy parameter and if this method is being used
-// to control tenancy the parameter must be checked. The method IsResourceAuthorizedToUser checks the use_tenancy parameter
-// and should be used for this purpose in most cases.
func GetUserTenantListTx(user auth.CurrentUser, tx *sql.Tx) ([]tc.TenantNullable, error) {
query := `WITH RECURSIVE q AS (SELECT id, name, active, parent_id, last_updated FROM tenant WHERE id = $1
UNION SELECT t.id, t.name, t.active, t.parent_id, t.last_updated FROM tenant t JOIN q ON q.id = t.parent_id)
@@ -176,19 +165,7 @@ SELECT id FROM user_tenant_children;
return tenants, nil
}
-// IsTenancyEnabledTx returns true if tenancy is enabled or false otherwise
-func IsTenancyEnabledTx(tx *sql.Tx) (bool, error) {
- query := `SELECT COALESCE(value::boolean,FALSE) AS value FROM parameter WHERE name = 'use_tenancy' AND config_file = 'global' UNION ALL SELECT FALSE FETCH FIRST 1 ROW ONLY`
- useTenancy := false
- err := tx.QueryRow(query).Scan(&useTenancy)
- if err != nil {
- return false, errors.New("checking if tenancy is enabled: " + err.Error())
- }
- return useTenancy, nil
-}
-
// IsResourceAuthorizedToUserTx returns a boolean value describing if the user has access to the provided resource tenant id and an error
-// If use_tenancy is set to false (0 in the db) this method will return true allowing access.
// If the user tenant is inactive (or any of its parent tenants are inactive), false will be returned.
func IsResourceAuthorizedToUserTx(resourceTenantID int, user *auth.CurrentUser, tx *sql.Tx) (bool, error) {
query := `
@@ -204,50 +181,32 @@ q AS (
SELECT id, active FROM tenant WHERE id = (select v from user_tenant_id)
UNION
SELECT t.id, t.active FROM TENANT t JOIN q ON q.id = t.parent_id
-),
-tenancy AS (
- SELECT
- COALESCE(value::boolean,FALSE) AS value
- FROM
- parameter
- WHERE
- name = 'use_tenancy'
- AND config_file = 'global'
- UNION ALL SELECT FALSE
- FETCH FIRST 1 ROW ONLY
)
SELECT
id,
- (select bool_and(active) from user_tenant_parents) as active,
- tenancy.value AS use_tenancy
+ (select bool_and(active) from user_tenant_parents) as active
FROM
- tenancy,
q
WHERE
id = (select v from resource_tenant_id)
-UNION ALL SELECT -1, false, tenancy.value AS use_tenancy FROM tenancy
+UNION ALL SELECT -1, false
FETCH FIRST 1 ROW ONLY;
`
var tenantID int
var active bool
- var useTenancy bool
log.Debugln("\nQuery: ", query)
- err := tx.QueryRow(query, user.TenantID, resourceTenantID).Scan(&tenantID, &active, &useTenancy)
+ err := tx.QueryRow(query, user.TenantID, resourceTenantID).Scan(&tenantID, &active)
switch {
case err != nil:
log.Errorf("Error checking user tenant %v access on resourceTenant %v: %v", user.TenantID, resourceTenantID, err.Error())
return false, err
default:
- if !useTenancy {
- return true, nil
- }
if active && tenantID == resourceTenantID {
return true, nil
} else {
- fmt.Printf("default")
return false, nil
}
}
@@ -266,41 +225,3 @@ func getDSTenantIDByIDTx(tx *sql.Tx, id int) (*int, bool, error) {
}
return tenantID, true, nil
}
-
-type Tenanter interface {
- TenantID() *int
- Name() string
- GetType() string
-}
-
-// FilterAuthorized takes a slice of objects, and returns only the objects the given user is authorized for.
-func FilterAuthorized(objs []Tenanter, user *auth.CurrentUser, tx *sql.Tx) ([]interface{}, error) {
- tenancyEnabled, err := IsTenancyEnabledTx(tx)
- if err != nil {
- return nil, errors.New("Error checking if tenancy enabled.")
- }
- if !tenancyEnabled {
- newObjs := []interface{}{}
- for _, obj := range objs {
- newObjs = append(newObjs, obj)
- }
- return newObjs, nil
- }
-
- newObjs := []interface{}{}
- for _, obj := range objs {
- if obj.TenantID() == nil {
- return nil, fmt.Errorf("FilterAuthorized for %T %s %s: no tenant ID", obj, obj.Name(), obj.GetType())
- }
- // TODO add/use a helper func to make a single SQL call, for performance
- ok, err := IsResourceAuthorizedToUserTx(*obj.TenantID(), user, tx)
- if err != nil {
- return nil, fmt.Errorf("FilterAuthorized for %T %s %s: no tenant ID", obj, obj.Name(), obj.GetType())
- }
- if !ok {
- continue
- }
- newObjs = append(newObjs, obj)
- }
- return newObjs, nil
-}