You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2017/04/02 22:09:42 UTC

[1/9] incubator-trafficcontrol git commit: org-tenancy: comment removal

Repository: incubator-trafficcontrol
Updated Branches:
  refs/heads/master 5105b6c4a -> ab3da011d


org-tenancy: comment removal


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

Branch: refs/heads/master
Commit: 8b099821d3bc97a9698f9e3fb7923154f666bdac
Parents: d9b7693
Author: nir-sopher <ni...@gmail.com>
Authored: Sat Apr 1 23:23:44 2017 +0300
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 traffic_ops/app/t/api/1.2/tenant.t | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/8b099821/traffic_ops/app/t/api/1.2/tenant.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/tenant.t b/traffic_ops/app/t/api/1.2/tenant.t
index 7ebc8a6..a66a8a3 100644
--- a/traffic_ops/app/t/api/1.2/tenant.t
+++ b/traffic_ops/app/t/api/1.2/tenant.t
@@ -152,7 +152,6 @@ ok $t->delete_ok('/api/1.2/tenants/' . $tenantE_id)->status_is(200)->or( sub { d
 ok $t->delete_ok('/api/1.2/tenants/' . $tenantD_id)->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 ok $t->delete_ok('/api/1.2/tenants/' . $tenantA_id)->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 
-#TODO(nirs): move to a "tenancy" UT when written
 #cannot delete a tenant that have a user
 ok $t->delete_ok('/api/1.2/tenants/' . 10**9)->status_is(400)
 	->json_is( "/alerts/0/text" => "Tenant 'root' is assign with user(s): e.g. 'admin-root'. Please update these users and retry." )


[5/9] incubator-trafficcontrol git commit: A tenant cannot be deleted if a user is assigned to it

Posted by mi...@apache.org.
A tenant cannot be deleted if a user is assigned to it


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

Branch: refs/heads/master
Commit: 0219eded052f81920332fc9e1324b52c320aca8f
Parents: 659f72d
Author: nir-sopher <ni...@gmail.com>
Authored: Mon Mar 20 10:44:26 2017 +0200
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 traffic_ops/app/lib/API/Tenant.pm  | 7 +++++++
 traffic_ops/app/t/api/1.2/tenant.t | 6 ++++++
 2 files changed, 13 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0219eded/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 bb62c64..d9167e7 100644
--- a/traffic_ops/app/lib/API/Tenant.pm
+++ b/traffic_ops/app/lib/API/Tenant.pm
@@ -224,6 +224,13 @@ sub delete {
 		return $self->alert("Tenant '$name' has children tenant(s): e.g '$existing_child'. Please update these tenants and retry.");
 	}
 
+	#The order of the below tests is intentional - allowing UT to cover all cases - TODO(nirs) remove this comment when a full "tenancy" UT is added, including permissions and such (no use in putting effort into it yet)
+
+	my $existing_user = $self->db->resultset('TmUser')->search( { tenant_id => $id })->get_column('username')->first();
+	if ($existing_user) {
+		return $self->alert("Tenant '$name' is assign with user(s): e.g. '$existing_user'. Please update these users and retry.");
+	}
+
 	my $rs = $tenant->delete();
 	if ($rs) {
 		return $self->success_message("Tenant deleted.");

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/0219eded/traffic_ops/app/t/api/1.2/tenant.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/tenant.t b/traffic_ops/app/t/api/1.2/tenant.t
index def39ae..7ebc8a6 100644
--- a/traffic_ops/app/t/api/1.2/tenant.t
+++ b/traffic_ops/app/t/api/1.2/tenant.t
@@ -152,6 +152,12 @@ ok $t->delete_ok('/api/1.2/tenants/' . $tenantE_id)->status_is(200)->or( sub { d
 ok $t->delete_ok('/api/1.2/tenants/' . $tenantD_id)->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 ok $t->delete_ok('/api/1.2/tenants/' . $tenantA_id)->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 
+#TODO(nirs): move to a "tenancy" UT when written
+#cannot delete a tenant that have a user
+ok $t->delete_ok('/api/1.2/tenants/' . 10**9)->status_is(400)
+	->json_is( "/alerts/0/text" => "Tenant 'root' is assign with user(s): e.g. 'admin-root'. Please update these users and retry." )
+	->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
 ok $t->get_ok('/logout')->status_is(302)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 $dbh->disconnect();
 done_testing();


[3/9] incubator-trafficcontrol git commit: UI: new user tenancy is derived from the creating user

Posted by mi...@apache.org.
UI: new user tenancy is derived from the creating user


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

Branch: refs/heads/master
Commit: 659f72d1c0501919ff2be64bf24027c5a5226a3e
Parents: 3cbbb81
Author: nir-sopher <ni...@gmail.com>
Authored: Mon Mar 20 10:43:31 2017 +0200
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 traffic_ops/app/lib/UI/User.pm | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/659f72d1/traffic_ops/app/lib/UI/User.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/UI/User.pm b/traffic_ops/app/lib/UI/User.pm
index 8d981b6..d21cbd9 100644
--- a/traffic_ops/app/lib/UI/User.pm
+++ b/traffic_ops/app/lib/UI/User.pm
@@ -288,6 +288,7 @@ sub create_user {
 		{
 			full_name            => $self->param('tm_user.full_name'),
 			username             => $self->param('tm_user.username'),
+			tenant_id            => current_user_tenant($self), #Tenancy is not dealt by the UI for now. getting the tenancy from the user			
 			public_ssh_key       => $self->param('tm_user.public_ssh_key'),
 			phone_number         => $self->param('tm_user.phone_number'),
 			email                => $self->param('tm_user.email'),


[2/9] incubator-trafficcontrol git commit: Org tenancy - users - minor fixes following a review: * Cannot remove "current user" tenancy * Comments

Posted by mi...@apache.org.
Org tenancy - users - minor fixes following a review:
* Cannot remove "current user" tenancy
* Comments


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

Branch: refs/heads/master
Commit: d9b7693ba3c7836665c39b4bf18f93e517be8da6
Parents: 97764b1
Author: nir-sopher <ni...@gmail.com>
Authored: Sat Apr 1 22:10:21 2017 +0300
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 traffic_ops/app/lib/API/Tenant.pm |  2 --
 traffic_ops/app/lib/API/User.pm   |  7 ++-----
 traffic_ops/app/t/api/1.2/user.t  | 13 ++-----------
 3 files changed, 4 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d9b7693b/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 d9167e7..4b74e25 100644
--- a/traffic_ops/app/lib/API/Tenant.pm
+++ b/traffic_ops/app/lib/API/Tenant.pm
@@ -224,8 +224,6 @@ sub delete {
 		return $self->alert("Tenant '$name' has children tenant(s): e.g '$existing_child'. Please update these tenants and retry.");
 	}
 
-	#The order of the below tests is intentional - allowing UT to cover all cases - TODO(nirs) remove this comment when a full "tenancy" UT is added, including permissions and such (no use in putting effort into it yet)
-
 	my $existing_user = $self->db->resultset('TmUser')->search( { tenant_id => $id })->get_column('username')->first();
 	if ($existing_user) {
 		return $self->alert("Tenant '$name' is assign with user(s): e.g. '$existing_user'. Please update these users and retry.");

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d9b7693b/traffic_ops/app/lib/API/User.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/API/User.pm b/traffic_ops/app/lib/API/User.pm
index 51b68e8..34af5e6 100644
--- a/traffic_ops/app/lib/API/User.pm
+++ b/traffic_ops/app/lib/API/User.pm
@@ -161,7 +161,7 @@ sub update {
 		return $self->not_found();
 	}
 
-	#setting tenant_id to undef if tenant is not set. TODO(nirs): remove when tenancy is no longer optional in the API
+	#setting tenant_id to undef if tenant is not set. 
  	my $tenant_id = exists($params->{tenantId}) ? $params->{tenantId} :  undef; 
  	
 	my $values = {
@@ -385,8 +385,7 @@ sub update_current {
 		if ( defined( $user->{"username"} ) ) {
 			$db_user->{"username"} = $user->{"username"};
 		}
-		if ( exists( $user->{"tenantId"} ) ) {
-		        #if value is not set, it will be kept as is. Keeping consistency. Using "exists" and not "defined" to allow data clearing
+		if ( defined( $user->{"tenantId"} ) ) {
  			$db_user->{"tenant_id"} = $user->{"tenantId"};
  		}
 		if ( defined( $user->{"public_ssh_key"} ) ) {
@@ -490,8 +489,6 @@ sub is_valid {
 				}
 			},
 			
-			#TODO(nirs) MAYBE when tenancy is not optional, add a tenant not null check
-
 		]
 	};
 

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/d9b7693b/traffic_ops/app/t/api/1.2/user.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/user.t b/traffic_ops/app/t/api/1.2/user.t
index bda22c1..d913043 100644
--- a/traffic_ops/app/t/api/1.2/user.t
+++ b/traffic_ops/app/t/api/1.2/user.t
@@ -79,7 +79,7 @@ sub run_ut {
 			->json_is( "/response/username", $login_user )
 			->json_is( "/response/tenantId", $tenant_id);
 
-		#removed the tenant
+		#cannot removed the tenant on current user
 		$t->post_ok( '/api/1.2/user/current/update',
 			json => { user => { username => $login_user, email => 'testportal1@kabletown.com', address_line1 => 'newaddress', tenantId => undef} } )
 			->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
@@ -87,17 +87,8 @@ sub run_ut {
 		#verify tenancy	
 		$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
 			->json_is( "/response/username", $login_user )
-			->json_is( "/response/tenantId", undef);
-	
-		#putting the tenant back the update with no "tenant" removed the tenant
-		$t->post_ok( '/api/1.2/user/current/update',
-			json => { user => { username => $login_user, email => 'testportal1@kabletown.com', address_line1 => 'newaddress', tenantId => $tenant_id} } )
-			->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
-			->json_is( "/alerts/0/text", "UserProfile was successfully updated." );
-		#verify tenancy	
-		$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
-			->json_is( "/response/username", $login_user )
 			->json_is( "/response/tenantId", $tenant_id);
+	
 	}
 	
 	# Ensure unique emails


[9/9] incubator-trafficcontrol git commit: This closes #398

Posted by mi...@apache.org.
This closes #398


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

Branch: refs/heads/master
Commit: ab3da011d610b1eb559c5e8e625ee25e4f12447f
Parents: 8b09982
Author: Jeremy Mitchell <mi...@gmail.com>
Authored: Sun Apr 2 16:09:34 2017 -0600
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:09:34 2017 -0600

----------------------------------------------------------------------

----------------------------------------------------------------------



[4/9] incubator-trafficcontrol git commit: Adding tenancy to the users table

Posted by mi...@apache.org.
Adding tenancy to the users table


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

Branch: refs/heads/master
Commit: 6903eaee44f86c53d2c962751b7e9358903b0890
Parents: 5105b6c
Author: nir-sopher <ni...@gmail.com>
Authored: Mon Mar 20 10:39:01 2017 +0200
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 .../migrations/20170315000001_user_tenancy.sql  | 31 ++++++++++
 .../app/lib/Fixtures/Integration/TmUser.pm      |  6 ++
 traffic_ops/app/lib/Fixtures/TmUser.pm          | 60 ++++++++++++++++++++
 traffic_ops/app/lib/Schema/Result/Tenant.pm     | 19 ++++++-
 traffic_ops/app/lib/Schema/Result/TmUser.pm     | 40 +++++++++++--
 5 files changed, 148 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/6903eaee/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql
----------------------------------------------------------------------
diff --git a/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql b/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql
new file mode 100644
index 0000000..9be1ca3
--- /dev/null
+++ b/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql
@@ -0,0 +1,31 @@
+/*
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+-- +goose Up
+-- SQL in section 'Up' is executed when this migration is applied
+
+
+ALTER TABLE tm_user
+    ADD tenant_id BIGINT,
+    ADD CONSTRAINT fk_tenantid FOREIGN KEY (tenant_id) REFERENCES tenant (id) MATCH FULL,
+    ALTER COLUMN tenant_id SET DEFAULT NULL;
+CREATE INDEX idx_k_tm_user_tenant_idx ON tm_user USING btree (tenant_id);
+
+-- +goose Down
+-- SQL section 'Down' is executed when this migration is rolled back
+
+ALTER TABLE tm_user
+DROP COLUMN tenant_id;
+

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/6903eaee/traffic_ops/app/lib/Fixtures/Integration/TmUser.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Fixtures/Integration/TmUser.pm b/traffic_ops/app/lib/Fixtures/Integration/TmUser.pm
index 0aa637a..37e3db6 100644
--- a/traffic_ops/app/lib/Fixtures/Integration/TmUser.pm
+++ b/traffic_ops/app/lib/Fixtures/Integration/TmUser.pm
@@ -31,6 +31,7 @@ my %definition_for = (
 		new => 'TmUser',
 		using => {
 		  username => 'admin',
+		  tenant_id => undef,
 		  local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
 		  uid => '1',
 		  role => '1',
@@ -59,6 +60,7 @@ my %definition_for = (
 			company => undef,
 			confirm_local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
 			username => 'codebig',
+			tenant_id => undef,
 			gid => '1',
 			country => 'United States',
 			state_or_province => 'state_or_province',
@@ -86,6 +88,7 @@ my %definition_for = (
 			confirm_local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
 			gid => '1',
 			username => 'extension',
+			tenant_id => undef,
 			country => 'United States',
 			email => 'plugin@email.com',
 			state_or_province => 'state_or_province',
@@ -111,6 +114,7 @@ my %definition_for = (
 			confirm_local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
 			company => undef,
 			username => 'migration',
+			tenant_id => undef,
 			gid => '1',
 			state_or_province => undef,
 			email => undef,
@@ -140,6 +144,7 @@ my %definition_for = (
 			country => 'United States',
 			gid => '1',
 			username => 'portal',
+			tenant_id => undef,
 			confirm_local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
 			company => undef,
 			local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
@@ -165,6 +170,7 @@ my %definition_for = (
 			state_or_province => 'state_or_province',
 			gid => '1',
 			username => 'testuser',
+			tenant_id => undef,
 			last_updated => '2015-12-10 15:43:45',
 			company => undef,
 			confirm_local_passwd => '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/6903eaee/traffic_ops/app/lib/Fixtures/TmUser.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Fixtures/TmUser.pm b/traffic_ops/app/lib/Fixtures/TmUser.pm
index eee7986..cbb546b 100644
--- a/traffic_ops/app/lib/Fixtures/TmUser.pm
+++ b/traffic_ops/app/lib/Fixtures/TmUser.pm
@@ -27,6 +27,7 @@ my %definition_for = (
 		using => {
 			id                   => 100,
 			username             => 'admin',
+			tenant_id            => undef,
 			role                 => 4,
 			uid                  => '1',
 			gid                  => '1',
@@ -51,6 +52,7 @@ my %definition_for = (
 		using => {
 			id                   => 200,
 			username             => 'portal',
+			tenant_id            => undef,
 			role                 => 6,
 			uid                  => '1',
 			gid                  => '1',
@@ -75,6 +77,7 @@ my %definition_for = (
 		using => {
 			id                   => 300,
 			username             => 'codebig',
+			tenant_id            => undef,
 			role                 => 6,
 			uid                  => '1',
 			gid                  => '1',
@@ -99,6 +102,7 @@ my %definition_for = (
 		using => {
 			id                   => 400,
 			username             => 'migration',
+			tenant_id            => undef,
 			role                 => 5,
 			uid                  => '1',
 			gid                  => '1',
@@ -123,6 +127,7 @@ my %definition_for = (
 		using => {
 			id                   => 500,
 			username             => 'federation',
+			tenant_id            => undef,
 			role                 => 7,
 			uid                  => '1',
 			gid                  => '1',
@@ -147,6 +152,7 @@ my %definition_for = (
 		using => {
 			id                   => 600,
 			username             => 'steering1',
+			tenant_id            => undef,
 			role                 => 7,
 			uid                  => '1',
 			gid                  => '1',
@@ -171,6 +177,7 @@ my %definition_for = (
 		using => {
 			id                   => 700,
 			username             => 'steering2',
+			tenant_id            => undef,
 			role                 => 7,
 			uid                  => '1',
 			gid                  => '1',
@@ -190,6 +197,59 @@ my %definition_for = (
 			registration_sent    => '1999-01-01 00:00:00',
 		},
 	},
+	
+	admin_root => {
+		new   => 'TmUser',
+		using => {
+			id                   => 800,
+			username             => 'admin-root',
+			tenant_id            => 10**9,
+			role                 => 4,
+			uid                  => '1',
+			gid                  => '1',
+			local_passwd         => $local_passwd,
+			confirm_local_passwd => $local_passwd,
+			full_name            => 'The Admin User for the "root" tenant',
+			email                => 'admin-root@kabletown.com',
+			new_user             => '1',
+			address_line1        => 'address_line1',
+			address_line2        => 'address_line2',
+			city                 => 'city',
+			state_or_province    => 'state_or_province',
+			phone_number         => '111-111-1111',
+			postal_code          => '80122',
+			country              => 'United States',
+			token                => '',
+			registration_sent    => '1999-01-01 00:00:00',
+		},
+	},
+	
+	portal_root => {
+		new   => 'TmUser',
+		using => {
+			id                   => 900,
+			username             => 'portal-root',
+			tenant_id            => 10**9,
+			role                 => 6,
+			uid                  => '1',
+			gid                  => '1',
+			local_passwd         => $local_passwd,
+			confirm_local_passwd => $local_passwd,
+			full_name            => 'The Portal User for the "root" tenant',
+			email                => 'portal-root@kabletown.com',
+			new_user             => '1',
+			address_line1        => 'address_line3',
+			address_line2        => 'address_line4',
+			city                 => 'city',
+			state_or_province    => 'state_or_province',
+			phone_number         => '222-222-2222',
+			postal_code          => '80122',
+			country              => 'United States',
+			token                => '',
+			registration_sent    => '1999-01-01 00:00:00',
+		},
+	},
+
 );
 
 sub get_definition {

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/6903eaee/traffic_ops/app/lib/Schema/Result/Tenant.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Schema/Result/Tenant.pm b/traffic_ops/app/lib/Schema/Result/Tenant.pm
index dd35a08..9f11084 100644
--- a/traffic_ops/app/lib/Schema/Result/Tenant.pm
+++ b/traffic_ops/app/lib/Schema/Result/Tenant.pm
@@ -148,9 +148,24 @@ __PACKAGE__->has_many(
   { cascade_copy => 0, cascade_delete => 0 },
 );
 
+=head2 tm_users
 
-# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-03-13 09:41:00
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:a816RdXB0mjimo2LvnqX/Q
+Type: has_many
+
+Related object: L<Schema::Result::TmUser>
+
+=cut
+
+__PACKAGE__->has_many(
+  "tm_users",
+  "Schema::Result::TmUser",
+  { "foreign.tenant_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-03-20 09:11:40
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:W4nbCNSj6N1gMar0mRvQ5Q
 
 
 # You can replace this text with custom code or comments, and it will be preserved on regeneration

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/6903eaee/traffic_ops/app/lib/Schema/Result/TmUser.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Schema/Result/TmUser.pm b/traffic_ops/app/lib/Schema/Result/TmUser.pm
index bc0abc9..91d57af 100644
--- a/traffic_ops/app/lib/Schema/Result/TmUser.pm
+++ b/traffic_ops/app/lib/Schema/Result/TmUser.pm
@@ -139,6 +139,12 @@ __PACKAGE__->table("tm_user");
   data_type: 'timestamp with time zone'
   is_nullable: 1
 
+=head2 tenant_id
+
+  data_type: 'bigint'
+  is_foreign_key: 1
+  is_nullable: 1
+
 =cut
 
 __PACKAGE__->add_columns(
@@ -196,6 +202,8 @@ __PACKAGE__->add_columns(
   { data_type => "text", is_nullable => 1 },
   "registration_sent",
   { data_type => "timestamp with time zone", is_nullable => 1 },
+  "tenant_id",
+  { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 },
 );
 
 =head1 PRIMARY KEY
@@ -212,7 +220,7 @@ __PACKAGE__->set_primary_key("id");
 
 =head1 UNIQUE CONSTRAINTS
 
-=head2 C<idx_54541_tmuser_email_unique>
+=head2 C<idx_89765_tmuser_email_unique>
 
 =over 4
 
@@ -222,9 +230,9 @@ __PACKAGE__->set_primary_key("id");
 
 =cut
 
-__PACKAGE__->add_unique_constraint("idx_54541_tmuser_email_unique", ["email"]);
+__PACKAGE__->add_unique_constraint("idx_89765_tmuser_email_unique", ["email"]);
 
-=head2 C<idx_54541_username_unique>
+=head2 C<idx_89765_username_unique>
 
 =over 4
 
@@ -234,7 +242,7 @@ __PACKAGE__->add_unique_constraint("idx_54541_tmuser_email_unique", ["email"]);
 
 =cut
 
-__PACKAGE__->add_unique_constraint("idx_54541_username_unique", ["username"]);
+__PACKAGE__->add_unique_constraint("idx_89765_username_unique", ["username"]);
 
 =head1 RELATIONS
 
@@ -318,9 +326,29 @@ __PACKAGE__->belongs_to(
   },
 );
 
+=head2 tenant
+
+Type: belongs_to
+
+Related object: L<Schema::Result::Tenant>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "tenant",
+  "Schema::Result::Tenant",
+  { id => "tenant_id" },
+  {
+    is_deferrable => 0,
+    join_type     => "LEFT",
+    on_delete     => "NO ACTION",
+    on_update     => "NO ACTION",
+  },
+);
+
 
-# Created by DBIx::Class::Schema::Loader v0.07046 @ 2016-11-18 22:45:19
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SGrZkCGhmXed7UzWMLYfOg
+# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-19 10:20:47
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2lI3iG0t7INKH+xQq+lo9g
 
 
 # You can replace this text with custom code or comments, and it will be preserved on regeneration


[6/9] incubator-trafficcontrol git commit: Org Tenancy - DB migration file rename (date)

Posted by mi...@apache.org.
Org Tenancy - DB migration file rename (date)


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

Branch: refs/heads/master
Commit: 97764b17547a6025f41eb67583cac6612b7c6ae2
Parents: 85b0557
Author: nir-sopher <ni...@gmail.com>
Authored: Sat Apr 1 21:43:54 2017 +0300
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 .../migrations/20170315000001_user_tenancy.sql  | 31 --------------------
 .../migrations/20170401000000_user_tenancy.sql  | 31 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/97764b17/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql
----------------------------------------------------------------------
diff --git a/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql b/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql
deleted file mode 100644
index 9be1ca3..0000000
--- a/traffic_ops/app/db/migrations/20170315000001_user_tenancy.sql
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-*/
-
--- +goose Up
--- SQL in section 'Up' is executed when this migration is applied
-
-
-ALTER TABLE tm_user
-    ADD tenant_id BIGINT,
-    ADD CONSTRAINT fk_tenantid FOREIGN KEY (tenant_id) REFERENCES tenant (id) MATCH FULL,
-    ALTER COLUMN tenant_id SET DEFAULT NULL;
-CREATE INDEX idx_k_tm_user_tenant_idx ON tm_user USING btree (tenant_id);
-
--- +goose Down
--- SQL section 'Down' is executed when this migration is rolled back
-
-ALTER TABLE tm_user
-DROP COLUMN tenant_id;
-

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/97764b17/traffic_ops/app/db/migrations/20170401000000_user_tenancy.sql
----------------------------------------------------------------------
diff --git a/traffic_ops/app/db/migrations/20170401000000_user_tenancy.sql b/traffic_ops/app/db/migrations/20170401000000_user_tenancy.sql
new file mode 100644
index 0000000..9be1ca3
--- /dev/null
+++ b/traffic_ops/app/db/migrations/20170401000000_user_tenancy.sql
@@ -0,0 +1,31 @@
+/*
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+-- +goose Up
+-- SQL in section 'Up' is executed when this migration is applied
+
+
+ALTER TABLE tm_user
+    ADD tenant_id BIGINT,
+    ADD CONSTRAINT fk_tenantid FOREIGN KEY (tenant_id) REFERENCES tenant (id) MATCH FULL,
+    ALTER COLUMN tenant_id SET DEFAULT NULL;
+CREATE INDEX idx_k_tm_user_tenant_idx ON tm_user USING btree (tenant_id);
+
+-- +goose Down
+-- SQL section 'Down' is executed when this migration is rolled back
+
+ALTER TABLE tm_user
+DROP COLUMN tenant_id;
+


[8/9] incubator-trafficcontrol git commit: User API - adding tenancy - documentation

Posted by mi...@apache.org.
User API - adding tenancy - documentation


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

Branch: refs/heads/master
Commit: 85b05575a0b446bb95630026cb80d8dc43c7a871
Parents: 0219ede
Author: nir-sopher <ni...@gmail.com>
Authored: Mon Mar 20 10:56:46 2017 +0200
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 .../development/traffic_ops_api/v12/user.rst      | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/85b05575/docs/source/development/traffic_ops_api/v12/user.rst
----------------------------------------------------------------------
diff --git a/docs/source/development/traffic_ops_api/v12/user.rst b/docs/source/development/traffic_ops_api/v12/user.rst
index b141eca..281ce3e 100644
--- a/docs/source/development/traffic_ops_api/v12/user.rst
+++ b/docs/source/development/traffic_ops_api/v12/user.rst
@@ -72,6 +72,8 @@ Users
   +----------------------+--------+------------------------------------------------+
   |``stateOrProvince``   | string |                                                |
   +----------------------+--------+------------------------------------------------+
+  | ``tenantId``         | int    | Owning tenant ID                               |
+  +----------------------+--------+------------------------------------------------+
   |``uid``               | string |                                                |
   +----------------------+--------+------------------------------------------------+
   |``username``          | string |                                                |
@@ -100,6 +102,7 @@ Users
 			"role": "6",
 			"rolename": "admin",
 			"stateOrProvince": "",
+			"tenantId": 1,
 			"uid": "0",
 			"username": "tsimpson"
 		 },
@@ -169,6 +172,8 @@ Users
   +----------------------+--------+------------------------------------------------+
   |``stateOrProvince``   | string |                                                |
   +----------------------+--------+------------------------------------------------+
+  | ``tenantId``         | int    | Owning tenant ID                               |
+  +----------------------+--------+------------------------------------------------+
   |``uid``               | string |                                                |
   +----------------------+--------+------------------------------------------------+
   |``username``          | string |                                                |
@@ -197,6 +202,7 @@ Users
 			"role": "6",
 			"rolename": "admin",
 			"stateOrProvince": "",
+			"tenantId": 1,
 			"uid": "0",
 			"username": "tsimpson"
 		 },
@@ -487,6 +493,8 @@ Users
   +----------------------+---------+------------------------------------------------+
   |``postalCode``        | string  |                                                |
   +----------------------+---------+------------------------------------------------+
+  | ``tenantId``         | int     | Owning tenant ID                               |
+  +----------------------+---------+------------------------------------------------+
 
   **Response Example** ::
 
@@ -508,7 +516,9 @@ Users
                             "role": "6",
                             "addressLine1": "",
                             "gid": "0",
-                            "postalCode": ""
+                            "postalCode": "",
+                            "tenantId": 1
+
            },
     }
 
@@ -561,6 +571,8 @@ Users
   +----------------------+---------+------------------------------------------------+
   |``postalCode``        | string  |                                                |
   +----------------------+---------+------------------------------------------------+
+  | ``tenantId``         | int     | Owning tenant ID                               |
+  +----------------------+---------+------------------------------------------------+
 
   **Request Example** ::
 
@@ -582,7 +594,9 @@ Users
         "role": "6",
         "addressLine1": "",
         "gid": "0",
-        "postalCode": ""
+        "postalCode": "",
+        "tenantId": 1,
+
      }
     }
 


[7/9] incubator-trafficcontrol git commit: adding tenant to the user API

Posted by mi...@apache.org.
adding tenant to the user API


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

Branch: refs/heads/master
Commit: 3cbbb81f6260087d0516f7e23dcec7da54d2f044
Parents: 6903eae
Author: nir-sopher <ni...@gmail.com>
Authored: Mon Mar 20 10:41:08 2017 +0200
Committer: Jeremy Mitchell <mi...@gmail.com>
Committed: Sun Apr 2 16:08:51 2017 -0600

----------------------------------------------------------------------
 traffic_ops/app/lib/API/User.pm        |  22 ++++-
 traffic_ops/app/lib/Test/TestHelper.pm |   6 ++
 traffic_ops/app/lib/UI/Utils.pm        |  14 +++-
 traffic_ops/app/t/api/1.2/user.t       | 119 ++++++++++++++++++++--------
 4 files changed, 125 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3cbbb81f/traffic_ops/app/lib/API/User.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/API/User.pm b/traffic_ops/app/lib/API/User.pm
index 690b176..51b68e8 100644
--- a/traffic_ops/app/lib/API/User.pm
+++ b/traffic_ops/app/lib/API/User.pm
@@ -97,7 +97,8 @@ sub index {
 				"rolename"        => $row->role->name,
 				"stateOrProvince" => $row->state_or_province,
 				"uid"             => $row->uid,
-				"username"        => $row->username
+				"username"        => $row->username,
+				"tenantId"        => $row->tenant_id
 			}
 		);
 	}
@@ -132,7 +133,8 @@ sub show {
 				"rolename"        => $row->role->name,
 				"stateOrProvince" => $row->state_or_province,
 				"uid"             => $row->uid,
-				"username"        => $row->username
+				"username"        => $row->username,
+				"tenantId"        => $row->tenant_id
 			}
 		);
 	}
@@ -159,6 +161,9 @@ sub update {
 		return $self->not_found();
 	}
 
+	#setting tenant_id to undef if tenant is not set. TODO(nirs): remove when tenancy is no longer optional in the API
+ 	my $tenant_id = exists($params->{tenantId}) ? $params->{tenantId} :  undef; 
+ 	
 	my $values = {
 		address_line1 			=> $params->{addressLine1},
 		address_line2 			=> $params->{addressLine2},
@@ -174,7 +179,9 @@ sub update {
 		registration_sent 		=> ( $params->{registrationSent} ) ? 1 : 0,
 		role 					=> $params->{role},
 		state_or_province 		=> $params->{stateOrProvince},
-		username 				=> $params->{username}
+		username 				=> $params->{username},
+		tenant_id 				=> $tenant_id
+		
 	};
 
 	if ( defined($params->{localPasswd}) && $params->{localPasswd} ne '' ) {
@@ -207,6 +214,7 @@ sub update {
 		$response->{stateOrProvince} 		= $rs->state_or_province;
 		$response->{uid} 					= $rs->uid;
 		$response->{username} 				= $rs->username;
+		$response->{tenantId} 				= $rs->tenant_id;
 
 		&log( $self, "Updated User with username '" . $rs->username . "' for id: " . $rs->id, "APICHANGE" );
 
@@ -277,6 +285,7 @@ sub current {
 			@data, {
 				"id"              => "0",
 				"username"        => $current_username,
+				"tenantId"	  => $self->current_user_tenant(),
 				"publicSshKey"  => "",
 				"role"            => $role,
 				"uid"             => "0",
@@ -321,6 +330,7 @@ sub current {
 					"phoneNumber"     => $row->phone_number,
 					"postalCode"      => $row->postal_code,
 					"country"         => $row->country,
+					"tenantId"        => $row->tenant_id,
 				}
 			);
 		}
@@ -375,6 +385,10 @@ sub update_current {
 		if ( defined( $user->{"username"} ) ) {
 			$db_user->{"username"} = $user->{"username"};
 		}
+		if ( exists( $user->{"tenantId"} ) ) {
+		        #if value is not set, it will be kept as is. Keeping consistency. Using "exists" and not "defined" to allow data clearing
+ 			$db_user->{"tenant_id"} = $user->{"tenantId"};
+ 		}
 		if ( defined( $user->{"public_ssh_key"} ) ) {
 			$db_user->{"public_ssh_key"} = $user->{"public_ssh_key"};
 		}
@@ -475,6 +489,8 @@ sub is_valid {
 					return $self->is_username_taken( $value, $params );
 				}
 			},
+			
+			#TODO(nirs) MAYBE when tenancy is not optional, add a tenant not null check
 
 		]
 	};

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3cbbb81f/traffic_ops/app/lib/Test/TestHelper.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Test/TestHelper.pm b/traffic_ops/app/lib/Test/TestHelper.pm
index b6d3174..2c57561 100644
--- a/traffic_ops/app/lib/Test/TestHelper.pm
+++ b/traffic_ops/app/lib/Test/TestHelper.pm
@@ -65,6 +65,12 @@ use constant STEERING_PASSWORD_1 => 'password';
 use constant STEERING_USER_2 => 'steering2';
 use constant STEERING_PASSWORD_2 => 'password';
 
+use constant ADMIN_ROOT_USER          => 'admin-root';
+use constant ADMIN_ROOT_USER_PASSWORD => 'password';
+
+use constant PORTAL_ROOT_USER          => 'portal-root';
+use constant PORTAL_ROOT_USER_PASSWORD => 'password';
+
 sub load_all_fixtures {
 	my $self    = shift;
 	my $fixture = shift;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3cbbb81f/traffic_ops/app/lib/UI/Utils.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/UI/Utils.pm b/traffic_ops/app/lib/UI/Utils.pm
index ddeb2d6..8345c0d 100644
--- a/traffic_ops/app/lib/UI/Utils.pm
+++ b/traffic_ops/app/lib/UI/Utils.pm
@@ -42,7 +42,7 @@ use constant ADMIN      => 30;
 our %EXPORT_TAGS = (
 	'all' => [
 		qw(trim_whitespace is_admin is_oper is_ldap is_privileged log is_ipaddress is_ip6address is_netmask in_same_net is_hostname admin_status_id type_id type_ids
-			profile_id profile_ids tm_version tm_url name_version_string is_regexp stash_role navbarpage rascal_hosts_by_cdn is_steering)
+			profile_id profile_ids tm_version tm_url name_version_string is_regexp stash_role navbarpage rascal_hosts_by_cdn is_steering defined_or_default current_user_tenant)
 	]
 );
 our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
@@ -401,4 +401,16 @@ sub exec_command {
 	return $result;
 }
 
+
+sub defined_or_default {
+	my $val = shift;
+	my $default = shift;
+	return defined($val) ? $val : $default;
+}
+
+sub current_user_tenant {
+    my $self = shift;
+    return $self->db->resultset('TmUser')->search( { username => $self->current_user()->{username} } )->get_column('tenant_id')->single();
+}    
+
 1;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3cbbb81f/traffic_ops/app/t/api/1.2/user.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/user.t b/traffic_ops/app/t/api/1.2/user.t
index 3501e8c..bda22c1 100644
--- a/traffic_ops/app/t/api/1.2/user.t
+++ b/traffic_ops/app/t/api/1.2/user.t
@@ -31,49 +31,104 @@ use Digest::SHA1 qw(sha1_hex);
 
 BEGIN { $ENV{MOJO_MODE} = "test" }
 
-my $dbh    = Schema->database_handle;
-my $schema = Schema->connect_to_database;
-my $t      = Test::Mojo->new('TrafficOps');
 
-Test::TestHelper->unload_core_data($schema);
-Test::TestHelper->teardown( $schema, 'Log' );
-Test::TestHelper->teardown( $schema, 'Role' );
-Test::TestHelper->teardown( $schema, 'TmUser' );
+sub run_ut {
+	my $t = shift;
+	my $schema = shift;
+	my $login_user = shift;
+	my $login_password = shift;
+
+	Test::TestHelper->unload_core_data($schema);
+	Test::TestHelper->teardown( $schema, 'Log' );
+	Test::TestHelper->teardown( $schema, 'Role' );
+	Test::TestHelper->teardown( $schema, 'TmUser' );
+
+	Test::TestHelper->load_core_data($schema);
+	
+	my $tenant_id = $schema->resultset('TmUser')->find( { username => $login_user } )->get_column('tenant_id');
+	my $tenant_name = defined ($tenant_id) ? $schema->resultset('Tenant')->find( { id => $tenant_id } )->get_column('name') : "null";
+
+	ok my $portal_user = $schema->resultset('TmUser')->find( { username => $login_user } ), 'Tenant $tenant_name: Does the portal user exist?';
 
-Test::TestHelper->load_core_data($schema);
+	# Verify the Portal user
+	$t->post_ok( '/api/1.2/user/login', json => { u => $login_user, p => $login_password} )->status_is(200);
+	$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+		->json_is( "/response/username", $login_user )
+		->json_is( "/response/tenantId", $tenant_id);
 
-ok my $portal_user = $schema->resultset('TmUser')->find( { username => Test::TestHelper::PORTAL_USER } ), 'Does the portal user exist?';
+	# Test required fields
+	$t->post_ok( '/api/1.2/user/current/update',
+		json => { user => { username => $login_user, email => 'testportal1@kabletown.com', address_line1 => 'newaddress', tenantId => $tenant_id} } )
+		->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+		->json_is( "/alerts/0/text", "UserProfile was successfully updated." );
+	
+	#verify tenancy	
+	$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+		->json_is( "/response/username", $login_user )
+		->json_is( "/response/tenantId", $tenant_id);
 
-# Verify the Portal user
-$t->post_ok( '/api/1.2/user/login', json => { u => Test::TestHelper::PORTAL_USER, p => Test::TestHelper::PORTAL_USER_PASSWORD } )->status_is(200);
-$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
-	->json_is( "/response/username", Test::TestHelper::PORTAL_USER );
+	# Test required fields
+	if (defined($tenant_id)){
+		#verify the update with no "tenant" do not removed the tenant
+		$t->post_ok( '/api/1.2/user/current/update',
+			json => { user => { username => $login_user, email => 'testportal1@kabletown.com', address_line1 => 'newaddress'} } )
+			->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+			->json_is( "/alerts/0/text", "UserProfile was successfully updated." );
+		#verify tenancy	
+		$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+			->json_is( "/response/username", $login_user )
+			->json_is( "/response/tenantId", $tenant_id);
 
-# Test required fields
-$t->post_ok( '/api/1.2/user/current/update',
-	json => { user => { username => Test::TestHelper::PORTAL_USER, email => 'testportal1@kabletown.com', address_line1 => 'newaddress' } } )
-	->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/text", "UserProfile was successfully updated." );
+		#removed the tenant
+		$t->post_ok( '/api/1.2/user/current/update',
+			json => { user => { username => $login_user, email => 'testportal1@kabletown.com', address_line1 => 'newaddress', tenantId => undef} } )
+			->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+			->json_is( "/alerts/0/text", "UserProfile was successfully updated." );
+		#verify tenancy	
+		$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+			->json_is( "/response/username", $login_user )
+			->json_is( "/response/tenantId", undef);
+	
+		#putting the tenant back the update with no "tenant" removed the tenant
+		$t->post_ok( '/api/1.2/user/current/update',
+			json => { user => { username => $login_user, email => 'testportal1@kabletown.com', address_line1 => 'newaddress', tenantId => $tenant_id} } )
+			->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+			->json_is( "/alerts/0/text", "UserProfile was successfully updated." );
+		#verify tenancy	
+		$t->get_ok('/api/1.2/user/current.json')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )
+			->json_is( "/response/username", $login_user )
+			->json_is( "/response/tenantId", $tenant_id);
+	}
+	
+	# Ensure unique emails
+	ok $t->post_ok( '/api/1.2/user/current/update', json => { user => { username => $login_user, email => 'testportal1@kabletown.com', tenantId => $tenant_id } } )
+		->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/level", "success" ),
+		"Tenant $tenant_name: Verify that the emails are unique";
 
-# Ensure unique emails
-ok $t->post_ok( '/api/1.2/user/current/update', json => { user => { username => Test::TestHelper::PORTAL_USER, email => 'testportal1@kabletown.com' } } )
-	->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/level", "success" ),
-	"Verify that the emails are unique";
+	ok $t->post_ok( '/api/1.2/user/current/update', json => { user => { username => $login_user, email => '@kabletown.com', tenantId => $tenant_id } } )
+		->status_is(400)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/level", "error" ),
+		"Tenant $tenant_name: Verify that the emails are properly formatted";
 
-ok $t->post_ok( '/api/1.2/user/current/update', json => { user => { username => Test::TestHelper::PORTAL_USER, email => '@kabletown.com' } } )
-	->status_is(400)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/level", "error" ),
-	"Verify that the emails are properly formatted";
+	ok $t->post_ok( '/api/1.2/user/current/update', json => { user => { username => $login_user, email => '@kabletown.com', tenantId => $tenant_id } } )
+		->status_is(400)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/level", "error" ),
+		"Tenant $tenant_name: Verify that the usernames are unique";
 
-ok $t->post_ok( '/api/1.2/user/current/update', json => { user => { username => Test::TestHelper::PORTAL_USER, email => '@kabletown.com' } } )
-	->status_is(400)->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/level", "error" ),
-	"Verify that the usernames are unique";
+	$t->post_ok( '/api/1.2/user/current/update', json => { user => { email => 'testportal1@kabletown.com', tenantId => $tenant_id } } )->status_is(400)
+		->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/text", "username is required" );
 
-$t->post_ok( '/api/1.2/user/current/update', json => { user => { email => 'testportal1@kabletown.com' } } )->status_is(400)
-	->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/text", "username is required" );
+	$t->post_ok( '/api/1.2/user/current/update', json => { user => { username => $login_user, tenantId => $tenant_id } } )->status_is(400)
+		->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/text", "email is required" );
+
+	ok $t->post_ok('/api/1.2/user/logout')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } );
+}
+
+my $dbh    = Schema->database_handle;
+my $schema = Schema->connect_to_database;
+my $t      = Test::Mojo->new('TrafficOps');
 
-$t->post_ok( '/api/1.2/user/current/update', json => { user => { username => Test::TestHelper::PORTAL_USER } } )->status_is(400)
-	->or( sub { diag $t->tx->res->content->asset->{content}; } )->json_is( "/alerts/0/text", "email is required" );
+run_ut($t, $schema, Test::TestHelper::PORTAL_USER,  Test::TestHelper::PORTAL_USER_PASSWORD);
+run_ut($t, $schema, Test::TestHelper::PORTAL_ROOT_USER,  Test::TestHelper::PORTAL_ROOT_USER_PASSWORD);
 
-ok $t->post_ok('/api/1.2/user/logout')->status_is(200)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 $dbh->disconnect();
 
 done_testing();