From 5ff48f0fb46521e64c690ec18a7872ccd8acb6d1 Mon Sep 17 00:00:00 2001 From: Patrick Schmitz Date: Fri, 7 Dec 2012 10:22:22 -0800 Subject: [PATCH] CSPACE-5657 Added support in DB and services for disabled tenants. This is first step, but works as far as it goes. Only control is directly through DB. To upgrade existing tenants, must just add a boolean column to the tenants table in cspace DB. See delta on the account.sql for the specifics. --- .../src/main/webapp/WEB-INF/login.conf | 6 ++-- .../src/main/resources/accounts_common.xsd | 9 +++++ .../src/main/resources/db/mysql/account.sql | 2 +- .../main/resources/db/postgresql/account.sql | 2 +- .../authentication/realm/CSpaceRealm.java | 8 ++++- .../realm/db/CSpaceDbRealm.java | 33 +++++++++++-------- .../main/resources/config/login-config.xml | 5 ++- .../AuthorizationCommon.java | 2 +- .../common/security/SecurityInterceptor.java | 13 +++++++- 9 files changed, 59 insertions(+), 21 deletions(-) diff --git a/services/JaxRsServiceProvider/src/main/webapp/WEB-INF/login.conf b/services/JaxRsServiceProvider/src/main/webapp/WEB-INF/login.conf index 98ba006d2..c8eddb09c 100644 --- a/services/JaxRsServiceProvider/src/main/webapp/WEB-INF/login.conf +++ b/services/JaxRsServiceProvider/src/main/webapp/WEB-INF/login.conf @@ -6,7 +6,8 @@ CSpaceJBossDBLoginModule { principalClass="org.collectionspace.authentication.CSpacePrincipal" principalsQuery="select passwd from users where username=?" rolesQuery="select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid" - tenantsQuery="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id" + tenantsQueryWithDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id" + tenantsQueryNoDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id and NOT t.disabled" debug=true; }; @@ -18,6 +19,7 @@ CSpaceJBossDBLoginModule { principalClass="org.collectionspace.authentication.CSpacePrincipal" principalsQuery="select passwd from users where username=?" rolesQuery="select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid" - tenantsQuery="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id" + tenantsQueryWithDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id" + tenantsQueryNoDisabled="select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id and NOT t.disabled" debug=true; }; diff --git a/services/account/jaxb/src/main/resources/accounts_common.xsd b/services/account/jaxb/src/main/resources/accounts_common.xsd index bde9eca83..db61f4556 100644 --- a/services/account/jaxb/src/main/resources/accounts_common.xsd +++ b/services/account/jaxb/src/main/resources/accounts_common.xsd @@ -312,6 +312,15 @@ + + + + + + + + + diff --git a/services/account/pstore/src/main/resources/db/mysql/account.sql b/services/account/pstore/src/main/resources/db/mysql/account.sql index fd92a4110..b66c09495 100644 --- a/services/account/pstore/src/main/resources/db/mysql/account.sql +++ b/services/account/pstore/src/main/resources/db/mysql/account.sql @@ -4,5 +4,5 @@ drop table if exists accounts_tenants; drop table if exists tenants; create table accounts_common (csid varchar(128) not null, created_at datetime not null, email varchar(255) not null, metadata_protection varchar(255), mobile varchar(255), person_ref_name varchar(255), phone varchar(255), roles_protection varchar(255), screen_name varchar(128) not null, status varchar(15) not null, updated_at datetime, userid varchar(128) not null, primary key (csid)); create table accounts_tenants (HJID bigint not null auto_increment, tenant_id varchar(128) not null, TENANTS_ACCOUNTSCOMMON_CSID varchar(128), primary key (HJID)); -create table tenants (id varchar(128) not null, created_at datetime not null, name varchar(255) not null, updated_at datetime, primary key (id)); +create table tenants (id varchar(128) not null, created_at datetime not null, name varchar(255) not null, disabled tinyint(1) not null, updated_at datetime, primary key (id)); alter table accounts_tenants add index FKFDA649B05A9CEEB5 (TENANTS_ACCOUNTSCOMMON_CSID), add constraint FKFDA649B05A9CEEB5 foreign key (TENANTS_ACCOUNTSCOMMON_CSID) references accounts_common (csid); diff --git a/services/account/pstore/src/main/resources/db/postgresql/account.sql b/services/account/pstore/src/main/resources/db/postgresql/account.sql index 49f81aede..ad9c8585b 100644 --- a/services/account/pstore/src/main/resources/db/postgresql/account.sql +++ b/services/account/pstore/src/main/resources/db/postgresql/account.sql @@ -5,6 +5,6 @@ DROP TABLE IF EXISTS tenants CASCADE; DROP SEQUENCE IF EXISTS hibernate_sequence; create table accounts_common (csid varchar(128) not null, created_at timestamp not null, email varchar(255) not null, mobile varchar(255), person_ref_name varchar(255), phone varchar(255), screen_name varchar(128) not null, status varchar(15) not null, updated_at timestamp, userid varchar(128) not null, metadata_protection varchar(255), roles_protection varchar(255), primary key (csid)); create table accounts_tenants (HJID int8 not null, tenant_id varchar(128) not null, TENANTS_ACCOUNTSCOMMON_CSID varchar(128), primary key (HJID)); -create table tenants (id varchar(128) not null, created_at timestamp not null, name varchar(255) not null, updated_at timestamp, primary key (id)); +create table tenants (id varchar(128) not null, created_at timestamp not null, name varchar(255) not null, disabled boolean not null, updated_at timestamp, primary key (id)); alter table accounts_tenants add constraint FKFDA649B05A9CEEB5 foreign key (TENANTS_ACCOUNTSCOMMON_CSID) references accounts_common; create sequence hibernate_sequence; diff --git a/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/CSpaceRealm.java b/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/CSpaceRealm.java index d635916ef..c9336de06 100644 --- a/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/CSpaceRealm.java +++ b/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/CSpaceRealm.java @@ -53,8 +53,14 @@ public interface CSpaceRealm { /** * Obtain the tenants for the authenticated user. - * @return collection containing the roles + * @return collection containing the tenants */ public Collection getTenants(String username, String groupClassName) throws LoginException; + /** + * Obtain the tenants for the authenticated user, allowing access to disable tenants + * @return collection containing the tenants + */ + public Collection getTenants(String username, String groupClassName, boolean includeDisabledTenants) throws LoginException; + } diff --git a/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/db/CSpaceDbRealm.java b/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/db/CSpaceDbRealm.java index 759de6a2b..3a3b6de48 100644 --- a/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/db/CSpaceDbRealm.java +++ b/services/authentication/service/src/main/java/org/collectionspace/authentication/realm/db/CSpaceDbRealm.java @@ -88,7 +88,8 @@ public class CSpaceDbRealm implements CSpaceRealm { private String datasourceName; private String principalsQuery; private String rolesQuery; - private String tenantsQuery; + private String tenantsQueryNoDisabled; + private String tenantsQueryWithDisabled; private boolean suspendResume; /** @@ -108,9 +109,13 @@ public class CSpaceDbRealm implements CSpaceRealm { if (tmp != null) { rolesQuery = tmp.toString(); } - tmp = options.get("tenantsQuery"); + tmp = options.get("tenantsQueryNoDisabled"); if (tmp != null) { - tenantsQuery = tmp.toString(); + tenantsQueryNoDisabled = tmp.toString(); + } + tmp = options.get("tenantsQueryWithDisabled"); + if (tmp != null) { + tenantsQueryWithDisabled = tmp.toString(); } tmp = options.get("suspendResume"); if (tmp != null) { @@ -288,15 +293,21 @@ public class CSpaceDbRealm implements CSpaceRealm { return groupsMap.values(); } - + @Override + public Collection getTenants(String username, String groupClassName) throws LoginException { + return getTenants(username, groupClassName, false); + } + /** * Execute the tenantsQuery against the datasourceName to obtain the tenants for * the authenticated user. * @return collection containing the roles */ @Override - public Collection getTenants(String username, String groupClassName) throws LoginException { + public Collection getTenants(String username, String groupClassName, boolean includeDisabledTenants) throws LoginException { + String tenantsQuery = getTenantQuery(includeDisabledTenants); + if (logger.isDebugEnabled()) { logger.debug("getTenants using tenantsQuery: " + tenantsQuery + ", username: " + username); } @@ -308,10 +319,6 @@ public class CSpaceDbRealm implements CSpaceRealm { try { conn = getConnection(); - // Get the user role names - if (logger.isDebugEnabled()) { - logger.debug("Executing query: " + tenantsQuery + ", with username: " + username); - } ps = conn.prepareStatement(tenantsQuery); try { @@ -510,14 +517,14 @@ public class CSpaceDbRealm implements CSpaceRealm { /** * @return the tenantQuery */ - public String getTenantQuery() { - return tenantsQuery; + public String getTenantQuery(boolean includeDisabledTenants) { + return includeDisabledTenants?tenantsQueryWithDisabled:tenantsQueryNoDisabled; } /** * @param tenantQuery the tenantQuery to set - */ public void setTenantQuery(String tenantQuery) { - this.tenantsQuery = tenantQuery; + this.tenantsQueryNoDisabled = tenantQuery; } + */ } diff --git a/services/authentication/service/src/main/resources/config/login-config.xml b/services/authentication/service/src/main/resources/config/login-config.xml index 699cc5f6d..948145332 100644 --- a/services/authentication/service/src/main/resources/config/login-config.xml +++ b/services/authentication/service/src/main/resources/config/login-config.xml @@ -147,7 +147,10 @@ $Revision: 64598 $ select r.rolename, 'Role' from roles as r, accounts_roles as ar where ar.user_id=? and ar.role_id=r.csid - + + select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id and NOT t.disabled + + select t.id, t.name, 'Tenants' from accounts_common as a, accounts_tenants as at, tenants as t where a.userid=? and a.csid = at.TENANTS_ACCOUNTSCOMMON_CSID and at.tenant_id = t.id diff --git a/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java b/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java index 49975136b..383d1466f 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java +++ b/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java @@ -401,7 +401,7 @@ public class AuthorizationCommon { rs.close(); String insertTenantSQL = - "INSERT INTO tenants (id,name,created_at) VALUES (?,?, now())"; + "INSERT INTO tenants (id,name,disabled,created_at) VALUES (?,?,FALSE,now())"; pstmt = conn.prepareStatement(insertTenantSQL); // create a statement for(String tId : tenantInfo.keySet()) { if(existingTenants.contains(tId)) { diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java index 6cc115505..0b8c18393 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java @@ -180,7 +180,18 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn */ private void checkActive() throws WebApplicationException { String userId = AuthN.get().getUserId(); - String tenantId = AuthN.get().getCurrentTenantId(); //FIXME: REM - This variable 'tenantId' is never used. Why? + try { + // Need to ensure that user is associated to a tenant + String tenantId = AuthN.get().getCurrentTenantId(); + } catch (IllegalStateException ise) { + String msg = "User's account is not associated to any active tenants, userId=" + userId; + // Note the RFC on return types: + // If the request already included Authorization credentials, then the 401 response + // indicates that authorization has been refused for those credentials. + Response response = Response.status( + Response.Status.UNAUTHORIZED).entity(msg).type("text/plain").build(); + throw new WebApplicationException(ise, response); + } try { //can't use JAXB here as this runs from the common jar which cannot //depend upon the account service -- 2.47.3