TenantUtils - tenant resource tenancy test

Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/2eb94bff
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/2eb94bff
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/2eb94bff

Branch: refs/heads/master
Commit: 2eb94bff31f038d4755c42491b447e3766a8e840
Parents: 731ceb1
Author: nir-sopher <[email protected]>
Authored: Thu Jun 1 16:46:30 2017 +0300
Committer: Jeremy Mitchell <[email protected]>
Committed: Tue Jul 18 12:12:31 2017 -0600

----------------------------------------------------------------------
 traffic_ops/app/lib/API/Tenant.pm     | 69 +++++++++++++++++++-------
 traffic_ops/app/lib/UI/TenantUtils.pm | 79 ++++++++++++++++++++++++++++++
 2 files changed, 130 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/2eb94bff/traffic_ops/app/lib/API/Tenant.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/API/Tenant.pm 
b/traffic_ops/app/lib/API/Tenant.pm
index 265aad5..ca67365 100644
--- a/traffic_ops/app/lib/API/Tenant.pm
+++ b/traffic_ops/app/lib/API/Tenant.pm
@@ -45,15 +45,17 @@ sub index {
        my $tenantUtils = UI::TenantUtils->new($self);
        my @tenants_list = $tenantUtils->get_hierarchic_tenants_list();
        foreach my $row (@tenants_list) {
-               push(
-                       @data, {
-                               "id"           => $row->id,
-                               "name"         => $row->name,
-                               "active"       => \$row->active,
-                               "parentId"     => $row->parent_id,
-                               "parentName"   => ( defined $row->parent_id ) ? 
$idnames{ $row->parent_id } : undef,
-                       }
-               );
+               if ($tenantUtils->is_tenant_resource_readable($row->id)) {
+                       push(
+                               @data, {
+                                       "id"           => $row->id,
+                                       "name"         => $row->name,
+                                       "active"       => \$row->active,
+                                       "parentId"     => $row->parent_id,
+                                       "parentName"   => ( defined 
$row->parent_id ) ? $idnames{ $row->parent_id } : undef,
+                               }
+                       );
+               }
        }
        $self->success( \@data );
 }
@@ -71,17 +73,20 @@ sub show {
                $idnames{ $row->id } = $row->name;
        }
 
+       my $tenantUtils = UI::TenantUtils->new($self);
        my $rs_data = $self->db->resultset("Tenant")->search( { 'me.id' => $id 
});
        while ( my $row = $rs_data->next ) {
-               push(
-                       @data, {
-                               "id"           => $row->id,
-                               "name"         => $row->name,
-                               "active"       => \$row->active,
-                               "parentId"     => $row->parent_id,
-                               "parentName"   => ( defined $row->parent_id ) ? 
$idnames{ $row->parent_id } : undef,
-                       }
-               );
+               if ($tenantUtils->is_tenant_resource_readable($row->id)) {
+                       push(
+                               @data, {
+                                       "id"           => $row->id,
+                                       "name"         => $row->name,
+                                       "active"       => \$row->active,
+                                       "parentId"     => $row->parent_id,
+                                       "parentName"   => ( defined 
$row->parent_id ) ? $idnames{ $row->parent_id } : undef,
+                               }
+                       );
+               }
        }
        $self->success( \@data );
 }
@@ -134,6 +139,22 @@ sub update {
                return $self->alert("Root tenant cannot be in-active.");
        }
 
+       #this is a write operation, allowed only by parents of the tenant 
(which are the owners of the resource of type tenant) 
+       my $current_resource_tenancy = $self->db->resultset('Tenant')->search( 
{ id => $id } )->get_column('parent_id')->single();
+       if (!defined($current_resource_tenancy)) {
+               #no parent - the tenant is its-own owner
+               $current_resource_tenancy = $id;
+       }
+       
+       if 
(!$tenantUtils->is_tenant_resource_writeable($current_resource_tenancy)) {
+               return $self->alert("Current owning tenant is not under user's 
tenancy.");
+       }
+
+       if (!$tenantUtils->is_tenant_resource_writeable($params->{parentId})) {
+               return $self->alert("Parent tenant to be set is not under 
user's tenancy.");
+       }
+
+
        #operation      
        my $values = {
                name      => $params->{name},
@@ -186,6 +207,11 @@ sub create {
        if ( !defined($parent_id) ) {
                return $self->alert("Parent Id is required.");
        }
+       
+       my $tenantUtils = UI::TenantUtils->new($self);
+       if (!$tenantUtils->is_tenant_resource_writeable($params->{parentId})) {
+               return $self->alert("Parent tenant to be set is not under 
user's tenancy.");
+       }
 
        my $existing = $self->db->resultset('Tenant')->search( { name => $name 
} )->get_column('name')->single();
        if ($existing) {
@@ -246,6 +272,13 @@ sub delete {
                return $self->not_found();
        }       
 
+       my $parent_tenant = $tenant->parent_id;
+       
+       my $tenantUtils = UI::TenantUtils->new($self);
+       if (!$tenantUtils->is_tenant_resource_writeable($parent_tenant)) {
+               return $self->alert("Parent tenant is not under user's 
tenancy.");
+       }
+
        my $name = $tenant->name;
        
        my $existing_child = $self->db->resultset('Tenant')->search( { 
parent_id => $id }, {order_by => 'me.name' } )->get_column('name')->first();

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/2eb94bff/traffic_ops/app/lib/UI/TenantUtils.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/UI/TenantUtils.pm 
b/traffic_ops/app/lib/UI/TenantUtils.pm
index 44a7f17..a7a33e4 100644
--- a/traffic_ops/app/lib/UI/TenantUtils.pm
+++ b/traffic_ops/app/lib/UI/TenantUtils.pm
@@ -80,6 +80,21 @@ sub is_root_tenant {
        return !defined($self->{context}->db->resultset('Tenant')->search( { id 
=> $tenant_id } )->get_column('parent_id')->single()); 
 }
 
+sub is_tenant_resource_readable {
+    my $self = shift;
+    my $resource_tenancy = shift;
+    
+    return _is_resource_accessable ($self, $resource_tenancy, "r");
+}
+
+sub is_tenant_resource_writeable {
+    my $self = shift;
+    my $resource_tenancy = shift;
+    
+    return _is_resource_accessable ($self, $resource_tenancy, "w");
+}
+
+
 
 ##############################################################
 
@@ -119,4 +134,68 @@ sub _init_tenants_if_needed {
        }
 }
 
+sub _max_tenancy_heirarchy {
+       my $self = shift;
+       return 100;
+}
+
+sub _is_resource_accessable {
+       my $self = shift;
+       my $resource_tenant = shift;
+       my $operation = shift;
+
+       if (!defined($resource_tenant)) {
+               #the object has no tenancy - opened for all
+               return 1;
+       }
+
+       if (&is_ldap($self->{context})) {
+               if ($operation eq "r") {
+                       #ldap user, can read all tenants - temporary for now as 
an LDAP user as no tenant and is part of the TC operator.
+                       # should be removed when LDAP is gone
+                       return 1;
+               }
+               #ldap user, has no tenancy, cannot write anything
+               return 0;
+       }
+       
+       my $user_tenant = current_user_tenant($self);
+       if (!defined($user_tenant)) {
+               #the user has no tenancy, - cannot approach items with tenancy
+               return 0;
+       }
+
+       $self->_init_tenants_if_needed();
+       my $tenant_record = $self->{tenants_dict}->{$user_tenant};
+       my $is_active_tenant = $tenant_record->{row}->active;
+       if (! $is_active_tenant) {
+               #user tenant is in-active - cannot do any operation
+               return 0;
+       }
+
+       if ($user_tenant == $resource_tenant) {
+           #resource has same tenancy of the user, operations are allowed
+           return 1;
+       }
+
+       #checking if the user tenant is an ancestor of the resource tenant
+       for (my $depth = 0; $depth < $self->_max_tenancy_heirarchy(); $depth++) 
{
+       
+               if (!defined($resource_tenant)){
+                       #reached top tenant, resource is not under the user 
tenancy
+                       return 0;
+               }
+
+               if ($user_tenant == $resource_tenant) {
+                   #resource has child tenancy of the user, operations are 
allowed
+                   return 1;
+               }
+               
+               $resource_tenant =  
$self->{tenants_dict}->{$resource_tenant}->{parent};
+       };
+       
+       #not found - recursion limit, give only access to root tenant
+       return $self->is_root_tenant(current_user_tenant($self));
+}
+
 1;

Reply via email to