rogerrut 2004/11/30 10:19:11 Modified: components/sso/src/java/org/apache/jetspeed/sso/impl SSOSiteImpl.java PersistenceBrokerSSOProvider.java SSOPrincipalImpl.java components/sso/src/test/org/apache/jetspeed/sso TestSSOComponent.java components/sso/src/java/META-INF sso_repository.xml Log: Updated SSO Framework. The relationship between site/principal and remote principal is defined as following: --> each site can have multiple principals (Jetspeed user principal) --> each principals has a remote principal and an associated credential --> A jetspeed user can only have one remote principal/credential per site --> A site can be an url (IFrame) or an application instance (PHP) Revision Changes Path 1.4 +7 -7 jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/SSOSiteImpl.java Index: SSOSiteImpl.java =================================================================== RCS file: /home/cvs/jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/SSOSiteImpl.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SSOSiteImpl.java 29 Nov 2004 01:32:25 -0000 1.3 +++ SSOSiteImpl.java 30 Nov 2004 18:19:10 -0000 1.4 @@ -23,7 +23,7 @@ import org.apache.jetspeed.sso.SSOException; import org.apache.jetspeed.sso.SSOSite; import org.apache.jetspeed.security.om.InternalCredential; -import org.apache.jetspeed.security.om.InternalPrincipal; +import org.apache.jetspeed.sso.SSOPrincipal; /** * SSOSiteImpl @@ -194,7 +194,7 @@ * Adds the credentail to the credentials collection * */ - public void addPrincipal(InternalPrincipal principal) throws SSOException { + public void addPrincipal(SSOPrincipal principal) throws SSOException { boolean bStatus = false; try @@ -219,20 +219,20 @@ public void removePrincipal(long principalId) throws SSOException { boolean bStatus = false; - InternalPrincipal principalObj = null; + SSOPrincipal principalObj = null; Iterator itSitePrincipals = principals.iterator(); while (itSitePrincipals.hasNext() ) { - principalObj = (InternalPrincipal)itSitePrincipals.next(); + principalObj = (SSOPrincipal)itSitePrincipals.next(); if ( principalObj.getPrincipalId() == principalId) { try { // TODO: Removing results in an OJB exception. Ignore it for the moment but it needs to be fixed soon... - //bStatus = principals.remove(principalObj); - bStatus = true; + bStatus = principals.remove(principalObj); + //bStatus = true; } catch(Exception e) { 1.5 +295 -82 jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/PersistenceBrokerSSOProvider.java Index: PersistenceBrokerSSOProvider.java =================================================================== RCS file: /home/cvs/jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/PersistenceBrokerSSOProvider.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- PersistenceBrokerSSOProvider.java 29 Nov 2004 01:32:25 -0000 1.4 +++ PersistenceBrokerSSOProvider.java 30 Nov 2004 18:19:10 -0000 1.5 @@ -15,6 +15,7 @@ */ package org.apache.jetspeed.sso.impl; +import java.util.ArrayList; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; @@ -29,16 +30,18 @@ import org.apache.jetspeed.sso.SSOException; import org.apache.jetspeed.sso.SSOProvider; import org.apache.jetspeed.sso.SSOSite; - +import org.apache.jetspeed.sso.SSOPrincipal; import org.apache.jetspeed.sso.impl.SSOSiteImpl; import org.apache.jetspeed.sso.impl.SSOPrincipalImpl; + import org.apache.jetspeed.security.SecurityHelper; import org.apache.jetspeed.security.BasePrincipal; import org.apache.jetspeed.security.om.InternalCredential; -import org.apache.jetspeed.security.om.InternalPrincipal; +import org.apache.jetspeed.security.om.InternalUserPrincipal; import org.apache.jetspeed.security.om.impl.InternalCredentialImpl; +import org.apache.jetspeed.security.om.impl.InternalUserPrincipalImpl; import org.apache.jetspeed.security.spi.impl.DefaultPasswordCredentialImpl; import org.apache.ojb.broker.query.Criteria; @@ -80,17 +83,18 @@ return false; // no entry for site } + // Get the principal from the subject BasePrincipal principal = (BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class); String fullPath = principal.getFullPath(); - // Filter the credentials for the given principals - InternalCredential credential = getCredential(ssoSite, fullPath); + // Check if the principal has any remote principals + Collection remotePrincipals = getRemotePrincipalsForPrincipal(ssoSite, fullPath); - if (credential == null) - return false; + if (remotePrincipals == null || remotePrincipals.size() < 1) + return false; // No remote credentials for Principal else - return true; + return true; // User has credentials for site } /* (non-Javadoc) @@ -110,13 +114,11 @@ String fullPath = principal.getFullPath(); // Filter the credentials for the given principals - InternalCredential credential = getCredential(ssoSite, fullPath); + SSOContext context = getCredential(ssoSite, fullPath); - if ( credential == null) + if ( context == null) throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE); // no entry for site - SSOContext context = new SSOContextImpl(credential.getPrincipalId(), principal.getName(),credential.getValue()); - return context; } @@ -127,7 +129,7 @@ public void addCredentialsForSite(Subject subject, String remoteUser, String site, String pwd) throws SSOException { - // Check if the site already exists + // Check if an entry for the site already exists otherwise create a new one SSOSite ssoSite = getSSOSiteObject(site); if (ssoSite == null) { @@ -139,23 +141,33 @@ ssoSite.setAllowUserSet(true); } - // Get the Principal information + // Get the Principal information (logged in user) String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath(); - - InternalPrincipal principal = this.getPrincipalForPath(subject, fullPath); + String principalName = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getName(); + + // Add an entry for the principal to the site if it doesn't exist + SSOPrincipal principal = this.getPrincipalForSite(ssoSite, fullPath); if (principal == null) - throw new SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST); + throw new SSOException(SSOException.FAILED_ADDING_PRINCIPAL_TO_MAPPING_TABLE_FOR_SITE); - // New credential object + // Create a remote principal and add it to the principal + InternalUserPrincipalImpl remotePrincipal = new InternalUserPrincipalImpl(remoteUser); + remotePrincipal.setFullPath("/sso/user/"+ principalName + "/" + remoteUser); + + // New credential object for remote principal InternalCredentialImpl credential = - new InternalCredentialImpl(principal.getPrincipalId(), + new InternalCredentialImpl(remotePrincipal.getPrincipalId(), pwd, 0, DefaultPasswordCredentialImpl.class.getName()); - // Add credential to mapping table - ssoSite.addCredential(credential); - ssoSite.addPrincipal(principal); - + if ( remotePrincipal.getCredentials() == null) + remotePrincipal.setCredentials(new ArrayList(0)); + + remotePrincipal.getCredentials().add( credential); + + + principal.addRemotePrincipal(remotePrincipal); + // Update database and reset cache try { @@ -178,6 +190,10 @@ public void removeCredentialsForSite(Subject subject, String site) throws SSOException { + // Initailization + InternalUserPrincipal remotePrincipal = null; + SSOPrincipal principal = null; + //Get the site SSOSite ssoSite = getSSOSiteObject(site); if (ssoSite == null) @@ -187,22 +203,32 @@ // Get the Principal information String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath(); - - InternalPrincipal principal = this.getPrincipalForPath(subject, fullPath); - /* - * Should never happen except if the function gets invoked from outside the current credential store - */ - if (principal == null) - throw new SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST); - - // New credential object - InternalCredential credential = getCredential(ssoSite, fullPath); - - // Remove credential and principal from mapping - ssoSite.removeCredential(credential); - ssoSite.removePrincipal(principal.getPrincipalId()); - + try + { + // Remove remote principal from the association table + remotePrincipal = removeRemotePrincipalForPrincipal(ssoSite, fullPath); + + // Remove the principal association + principal = this.getPrincipalForSite(ssoSite, fullPath); + if ( principal != null ) + ssoSite.getPrincipals().remove(principal); + + // Remove Remote principal and associated credential from persistence store + if (remotePrincipal != null) + getPersistenceBrokerTemplate().delete(remotePrincipal); + + } + catch(SSOException ssoex) + { + throw new SSOException(ssoex); + } + catch (Exception e) + { + e.printStackTrace(); + throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() ); + } + // Update database and reset cache try { @@ -218,6 +244,67 @@ this.mapSite.clear(); } + /** + * updateCredentialsForSite + * @param subject Current subject + * @param remoteUser remote user login + * @param site URL or description of site + * @param pwd Password for credentail + */ + public void updateCredentialsForSite(Subject subject, String remoteUser, String site, String pwd) + throws SSOException + { + // Check if the the current user has a credential for the site + + // Update the credential + // Initailization + InternalUserPrincipal remotePrincipal = null; + + //Get the site + SSOSite ssoSite = getSSOSiteObject(site); + if (ssoSite == null) + { + throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE); + } + + // Get the Principal information + String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath(); + String principalName = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getName(); + + // Get collection of remote principals and find a match for the one to remove + Collection remotePrincipals = getRemotePrincipalsForPrincipal(ssoSite, fullPath); + if ( remotePrincipals == null || remotePrincipals.size() < 1) + throw new SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST); + + // User can have one remote user per site + Iterator itRemotePrincipals = remotePrincipals.iterator(); + remotePrincipal = (InternalUserPrincipal)itRemotePrincipals.next(); + + // Update principal information + remotePrincipal.setFullPath("/sso/user/"+ principalName + "/" + remoteUser); + InternalCredential credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next(); + + // New credential object + if ( credential != null) + // Remove credential and principal from mapping + credential.setValue(pwd); + + // Update database and reset cache + try + { + getPersistenceBrokerTemplate().store(ssoSite); + } + catch (Exception e) + { + e.printStackTrace(); + throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() ); + } + + // Clear cache + this.mapSite.clear(); + + } + /* * Helper utilities * @@ -275,82 +362,208 @@ * getCredential * returns the credentials for a given user */ - private InternalCredential getCredential(SSOSite ssoSite, String fullPath) + private SSOContext getCredential(SSOSite ssoSite, String fullPath) { - long principalID = -1; InternalCredential credential = null; + String remoteUser = null; + String remoteFullPath = null; /* Error checking * 1) should have at least one principal - * 2) should have at least one credential * * If one of the above fails return null wich means that the user doesn't have credentials for that site */ Collection principals = ssoSite.getPrincipals(); - Collection credentials = ssoSite.getCredentials(); - if ( principals == null || credentials == null) + if ( principals == null ) { return null; } + // Iterate over the principals and extract the principal id for the given full path + SSOPrincipal principal = null; + Iterator itPrincipals = principals.iterator(); - while (itPrincipals.hasNext() && principalID == -1 /*not found yet*/) + while (itPrincipals.hasNext() && principal == null /*not found yet*/) { - InternalPrincipal principal = (InternalPrincipal)itPrincipals.next(); - if ( principal != null && principal.getFullPath().compareToIgnoreCase(fullPath) == 0) + SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next(); + if ( tmp != null && tmp.getFullPath().compareToIgnoreCase(fullPath) == 0) { - principalID = principal.getPrincipalId(); + // Found it stop iteration + principal = tmp; } } - if ( principalID == -1) + if ( principal == null) return null; // No principal found for that site - // Last lookup to see if there are credentials for that user - Iterator itCredentials = credentials.iterator(); - while (itCredentials.hasNext() && credential == null /*not found yet*/) + // Extract the remote principal + Collection remotePrincipals = principal.getRemotePrincipals(); + if (remotePrincipals == null || remotePrincipals.size() < 1) + return null; // no remote principals + + InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)remotePrincipals.iterator().next(); + + // Get credentail for this remote user + if ( remotePrincipal.getCredentials() != null) + credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next(); + + // Error checking -- should have a credential at this point + if ( credential == null) { - InternalCredential cred = (InternalCredential)itCredentials.next(); - - if ( cred != null && cred.getPrincipalId() == principalID) + System.out.println("Warning: Remote User " + remotePrincipal.getFullPath() + " doesn't have a credential"); + return null; + } + else + { + System.out.println("Found Credential: " + credential.getValue() + " for PrincipalID " + remotePrincipal.getPrincipalId() + " Name: "+remotePrincipal.getFullPath() ); + } + + // Create new context + String name = remotePrincipal.getFullPath(); + int ix = name.lastIndexOf('/'); + if ( ix != -1) + name = name.substring(ix); + + SSOContext context = new SSOContextImpl(credential.getPrincipalId(), name, credential.getValue()); + + return context; + } + + /* + * Get a Collection of remote Principals for the logged in principal identified by the full path + */ + private Collection getRemotePrincipalsForPrincipal(SSOSite ssoSite, String fullPath) + { + // The site orincipals list contains a list of remote principals for the user + Collection principals = ssoSite.getPrincipals(); + + if ( principals == null ) + return null; // No principals for this site + + Iterator ixPrincipals = principals.iterator(); + while (ixPrincipals.hasNext()) + { + SSOPrincipal principal = (SSOPrincipal)ixPrincipals.next(); + if ( principal != null && principal.getFullPath().compareToIgnoreCase(fullPath) == 0) { - // Found credentials for Orincipals - // TODO: Remove debug - System.out.println("Found Credential: " + cred.getValue() + " for PrincipalID " + principalID); - credential = cred; + // Found Principal -- extract remote principals + return principal.getRemotePrincipals(); } } - return credential; + // Principal is not in list + return null; } - private InternalPrincipal getPrincipalForPath(Subject subject, String fullPath) + /* + * getPrincipalForSite() + * returns a principal that matches the full path for the site or creates a new entry if it doesn't exist + */ + private SSOPrincipal getPrincipalForSite(SSOSite ssoSite, String fullPath) { - Criteria filter = new Criteria(); - filter.addEqualTo("fullPath", fullPath); - - QueryByCriteria query = QueryFactory.newQuery(SSOPrincipalImpl.class, filter); - Collection principals = getPersistenceBrokerTemplate().getCollectionByQuery(query); - - if ( principals != null && principals.isEmpty() != true) - { - Iterator itPrincipals = principals.iterator(); - // Get the site from the collection. There should be only one entry (uniqueness) - if (itPrincipals.hasNext()) + SSOPrincipal principal = null; + + if ( ssoSite.getPrincipals() != null) + { + Iterator itPrincipals = ssoSite.getPrincipals().iterator(); + while (itPrincipals.hasNext() && principal == null) + { + SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next(); + if ( tmp != null && tmp.getFullPath().compareToIgnoreCase(fullPath) == 0) + principal = tmp; // Found existing entry + } + } + + // Not yest in the site list. Add it but make sure that a user exists + if ( principal == null) + { + Criteria filter = new Criteria(); + filter.addEqualTo("fullPath", fullPath); + + QueryByCriteria query = QueryFactory.newQuery(SSOPrincipalImpl.class, filter); + Collection principals = getPersistenceBrokerTemplate().getCollectionByQuery(query); + + if ( principals != null && principals.isEmpty() != true) { - return (InternalPrincipal) itPrincipals.next(); + Iterator itPrincipals = principals.iterator(); + // Get the site from the collection. There should be only one entry (uniqueness) + if (itPrincipals.hasNext()) + { + principal = (SSOPrincipal) itPrincipals.next(); + try + { + ssoSite.addPrincipal(principal); + } + catch (SSOException ssoex) + { + System.out.println("ERROR-SSO: Failed adding principal to principla map. Error: " + ssoex.getMessage()); + } + } } - } - - // Principal for path doesn't exist - return null; - + } + + return principal; + } + + /** + * getCredentialForPrincipal + * @param site + * @param principalId + * @return InternalCredential for the principal ID + */ + private InternalCredential getCredentialForPrincipal(SSOSite site, long principalId) + { + if ( site.getCredentials() != null) + { + Iterator itCredentials = site.getCredentials().iterator(); + while(itCredentials.hasNext() ) + { + InternalCredential tmp = (InternalCredential)itCredentials.next(); + if ( tmp != null && tmp.getPrincipalId() == principalId) + return tmp; + } + } + + return null; + } + + /** + * removeRemotePrincipalForPrincipal + * @param site + * @param fullPath + * @return + * + * removes remotePrincipal for a site & principal + */ + private InternalUserPrincipal removeRemotePrincipalForPrincipal(SSOSite site, String fullPath) throws SSOException + { + if (site.getPrincipals() != null) + { + Iterator itPrincipals = site.getPrincipals().iterator(); + while (itPrincipals.hasNext()) + { + SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next(); + if ( tmp.getFullPath().compareToIgnoreCase(fullPath) == 0) + { + // Found -- get the remotePrincipal + Collection collRemotePrincipals = tmp.getRemotePrincipals() ; + if (collRemotePrincipals != null) + { + + Iterator itRemotePrincipals = collRemotePrincipals.iterator(); + if (itRemotePrincipals.hasNext()) + { + InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)itRemotePrincipals.next(); + // Found remove the object + collRemotePrincipals.remove(remotePrincipal); + return remotePrincipal; + } + } + } + } + } + + throw new SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST); } - - public void updateCredentialsForSite(Subject subject, String remoteUser, String site, String pwd) - throws SSOException - { - - } } 1.2 +35 -2 jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/SSOPrincipalImpl.java Index: SSOPrincipalImpl.java =================================================================== RCS file: /home/cvs/jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/SSOPrincipalImpl.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SSOPrincipalImpl.java 16 Nov 2004 19:08:47 -0000 1.1 +++ SSOPrincipalImpl.java 30 Nov 2004 18:19:10 -0000 1.2 @@ -16,8 +16,11 @@ package org.apache.jetspeed.sso.impl; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Collection; -import org.apache.jetspeed.security.om.InternalPrincipal; + +import org.apache.jetspeed.security.om.InternalUserPrincipal; +import org.apache.jetspeed.sso.SSOPrincipal; /** * <p> @@ -28,7 +31,7 @@ * * @author <a href="mailto:rogerrut @apache.org">Roger Ruttimann</a> */ -public class SSOPrincipalImpl implements InternalPrincipal { +public class SSOPrincipalImpl implements SSOPrincipal { /** The principal id. */ private long principalId; @@ -52,6 +55,10 @@ /** Permissions not used by required by the interface*/ private Collection permissions; + + /** Remote principals for Principal */ + private Collection remotePrincipals; + /** * <p> @@ -89,6 +96,20 @@ this.creationDate = new Timestamp(System.currentTimeMillis()); this.modifiedDate = this.creationDate; } + + /** + * addRemotePrincipal() + * adds a principal to the list of remote principals + */ + public void addRemotePrincipal(InternalUserPrincipal principal) + { + if (remotePrincipals == null) + { + remotePrincipals = new ArrayList(1); + } + + remotePrincipals.add(principal); + } /** * @see org.apache.jetspeed.security.om.InternalPrincipal#getPrincipalId() @@ -218,5 +239,17 @@ { this.enabled = enabled; } + /** + * @return Returns the remotePrincipals. + */ + public Collection getRemotePrincipals() { + return remotePrincipals; + } + /** + * @param remotePrincipals The remotePrincipals to set. + */ + public void setRemotePrincipals(Collection remotePrincipals) { + this.remotePrincipals = remotePrincipals; + } } 1.5 +24 -1 jakarta-jetspeed-2/components/sso/src/test/org/apache/jetspeed/sso/TestSSOComponent.java Index: TestSSOComponent.java =================================================================== RCS file: /home/cvs/jakarta-jetspeed-2/components/sso/src/test/org/apache/jetspeed/sso/TestSSOComponent.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- TestSSOComponent.java 28 Nov 2004 02:23:49 -0000 1.4 +++ TestSSOComponent.java 30 Nov 2004 18:19:10 -0000 1.5 @@ -50,6 +50,9 @@ */ static private String TEST_URL= "http://localhost/jetspeed"; static private String TEST_USER= "joe"; + static private String REMOTE_USER= "remoteJS"; + static private String REMOTE_PWD_1 = "remote_1"; + static private String REMOTE_PWD_2 = "remote_2"; /** The property manager. */ @@ -121,7 +124,7 @@ // Add credential try { - ssoBroker.addCredentialsForSite(subject, "TODO", TEST_URL,"test"); + ssoBroker.addCredentialsForSite(subject, REMOTE_USER, TEST_URL,REMOTE_PWD_1); System.out.println("SSO Credential added for user:" + TEST_USER+ " site: " + TEST_URL); } catch(SSOException ssoex) @@ -135,6 +138,26 @@ { System.out.println("SSO Credential found for user:" + TEST_USER+ " site: " + TEST_URL); } + + // Test credential update + SSOContext ssocontext = ssoBroker.getCredentials(subject, TEST_URL); + System.out.println("SSO Credential: User:" + ssocontext.getUserName() + " Password: " + ssocontext.getPassword()); + + try + { + // Update Remote credential + System.out.println("SSO Credential Update" ); + ssoBroker.updateCredentialsForSite(subject, REMOTE_USER , TEST_URL, REMOTE_PWD_2); + + ssocontext = ssoBroker.getCredentials(subject, TEST_URL); + System.out.println("SSO Credential updated: User:" + ssocontext.getUserName() + " Password: " + ssocontext.getPassword()); + + } + catch(SSOException ssoex) + { + System.out.println("SSO Credential update FAILED for user:" + TEST_USER+ " site: " + TEST_URL); + throw new Exception(ssoex.getMessage()); + } try { 1.3 +16 -16 jakarta-jetspeed-2/components/sso/src/java/META-INF/sso_repository.xml Index: sso_repository.xml =================================================================== RCS file: /home/cvs/jakarta-jetspeed-2/components/sso/src/java/META-INF/sso_repository.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sso_repository.xml 22 Nov 2004 06:13:31 -0000 1.2 +++ sso_repository.xml 30 Nov 2004 18:19:11 -0000 1.3 @@ -78,6 +78,20 @@ nullable="false" > </field-descriptor> + <collection-descriptor + name="remotePrincipals" + element-class-ref="org.apache.jetspeed.security.om.impl.InternalUserPrincipalImpl" + proxy="true" + refresh="true" + auto-retrieve="true" + auto-update="object" + auto-delete="object" + indirection-table="SSO_PRINCIPAL_TO_REMOTE_PRINCIPAL" + > + <documentation>This is the reference to principals.</documentation> + <fk-pointing-to-this-class column="PRINCIPAL_ID"/> + <fk-pointing-to-element-class column="REMOTE_PRINCIPAL_ID"/> + </collection-descriptor> </class-descriptor> @@ -129,28 +143,14 @@ nullable="false" > </field-descriptor> - <collection-descriptor - name="credentials" - element-class-ref="org.apache.jetspeed.security.om.impl.InternalCredentialImpl" - proxy="true" - refresh="true" - auto-retrieve="true" - auto-update="object" - auto-delete="object" - indirection-table="SSO_SITE_TO_CREDENTIALS" - > - <documentation>This is the reference to credentials.</documentation> - <fk-pointing-to-this-class column="SITE_ID"/> - <fk-pointing-to-element-class column="CREDENTIAL_ID"/> - </collection-descriptor> <collection-descriptor name="principals" element-class-ref="org.apache.jetspeed.sso.impl.SSOPrincipalImpl" proxy="true" refresh="true" auto-retrieve="true" - auto-update="link" - auto-delete="link" + auto-update="object" + auto-delete="object" indirection-table="SSO_SITE_TO_PRINCIPALS" > <documentation>This is the reference to principals.</documentation>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]