rogerrut    2004/12/04 14:28:19

  Modified:    components/sso/src/java/org/apache/jetspeed/sso/impl
                        SSOSiteImpl.java PersistenceBrokerSSOProvider.java
               components/sso/src/test/org/apache/jetspeed/sso
                        TestSSOComponent.java
               components/sso/src/java/META-INF sso_repository.xml
  Log:
  Fix for SSO
  Entries where not unique to a user/site which required an new association 
table (SSO_SITE_TO_REMOTE)
  Re factored the code for the API to include the mapping table
  Updated Unit test
  
  Revision  Changes    Path
  1.5       +16 -3     
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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SSOSiteImpl.java  30 Nov 2004 18:19:10 -0000      1.4
  +++ SSOSiteImpl.java  4 Dec 2004 22:28:19 -0000       1.5
  @@ -43,8 +43,9 @@
        private boolean isAllowUserSet;
        private boolean isCertificateRequired;
        
  -     private Collection      credentials = new Vector();//= new ArrayList(0);
  -     private Collection      principals = new Vector();// = new ArrayList(0);
  +     private Collection      credentials = new Vector();
  +     private Collection      principals = new Vector();
  +     private Collection      remotePrincipals = new Vector();
        
        /**
         * 
  @@ -246,4 +247,16 @@
                                        
                        }
                }
  +    /**
  +     * @return Returns the remotePrincipals.
  +     */
  +    public Collection getRemotePrincipals() {
  +        return remotePrincipals;
  +    }
  +    /**
  +     * @param remotePrincipals The remotePrincipals to set.
  +     */
  +    public void setRemotePrincipals(Collection remotePrincipals) {
  +        this.remotePrincipals = remotePrincipals;
  +    }
   }
  
  
  
  1.9       +179 -106  
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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- PersistenceBrokerSSOProvider.java 3 Dec 2004 23:53:33 -0000       1.8
  +++ PersistenceBrokerSSOProvider.java 4 Dec 2004 22:28:19 -0000       1.9
  @@ -83,18 +83,32 @@
                        return false;   // no entry for site
                }
                
  -             
                // Get the principal from the subject
                BasePrincipal principal = 
(BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
                String fullPath = principal.getFullPath();
                
  -             //      Check if the principal has any remote principals
  -             Collection remotePrincipals = 
getRemotePrincipalsForPrincipal(ssoSite, fullPath);
  +             // Get remotePrincipals for Site and match them with the Remote 
Principal for the Principal attached to site
  +             Collection principalsForSite = ssoSite.getPrincipals();
  +             Collection remoteForSite = ssoSite.getRemotePrincipals();
  +             
  +             // If any of them don't exist just return
  +             if (principalsForSite == null || remoteForSite== null )
  +                 return false;       // no entry
  +             
  +             Collection remoteForPrincipals = 
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
                
  -             if (remotePrincipals == null || remotePrincipals.size() < 1)
  -                     return false;   // No remote credentials for Principal
  +             if ( remoteForPrincipals == null)
  +                 return false;       // no entry
  +             
  +             // Get remote Principal that matches the site and the principal
  +             if (FindRemoteMatch(remoteForPrincipals, remoteForSite) == null 
)
  +             {
  +                 return false;       // No entry
  +             }
                else
  -                     return true;    // User has credentials for site
  +             {
  +                 return true;        // Has an entry
  +             }
        }
   
        /* (non-Javadoc)
  @@ -148,10 +162,29 @@
                // Add an entry for the principal to the site if it doesn't 
exist
                SSOPrincipal principal = this.getPrincipalForSite(ssoSite, 
fullPath);
                
  +             if (principal == null )
  +             {
  +                 principal = getSSOPrincipa(fullPath);
  +                 ssoSite.addPrincipal(principal);
  +             }
  +             else
  +             {
  +                 // Check if the entry the user likes to update exists 
already
  +                 Collection remoteForSite = ssoSite.getRemotePrincipals();
  +                 if ( remoteForSite != null)
  +                 {
  +                     if (FindRemoteMatch(principal.getRemotePrincipals(), 
remoteForSite) != null )
  +                     {
  +                         // Entry exists can't to an add has to call update
  +                         throw new 
SSOException(SSOException.REMOTE_PRINCIPAL_EXISTS_CALL_UPDATE);
  +                     }
  +                 }
  +             }
  +             
                if (principal == null)
                        throw new 
SSOException(SSOException.FAILED_ADDING_PRINCIPAL_TO_MAPPING_TABLE_FOR_SITE);
                
  -             // Create a remote principal and add it to the principal
  +             // Create a remote principal and credentials
                InternalUserPrincipalImpl remotePrincipal = new 
InternalUserPrincipalImpl(remoteUser);
                remotePrincipal.setFullPath("/sso/user/"+ principalName + "/" + 
remoteUser);
        
  @@ -164,9 +197,12 @@
                        remotePrincipal.setCredentials(new ArrayList(0));
                 
                remotePrincipal.getCredentials().add( credential);
  -              
  -              
  -              principal.addRemotePrincipal(remotePrincipal);
  +             
  +             // Add it to Principals remotePrincipals list
  +             principal.addRemotePrincipal(remotePrincipal);
  +             
  +             // Update the site remotePrincipals list
  +             ssoSite.getRemotePrincipals().add(remotePrincipal);
                        
                // Update database and reset cache
                 try
  @@ -182,7 +218,6 @@
            this.mapSite.put(site, ssoSite);
            // Clear cache
            //this.mapSite.clear();
  -
        }
   
        /* (non-Javadoc)
  @@ -207,17 +242,31 @@
                
                try
                {
  -                     // Remove remote principal from the association table
  -                     remotePrincipal = 
removeRemotePrincipalForPrincipal(ssoSite, fullPath);
  +                     //      Get remotePrincipals for Site and match them 
with the Remote Principal for the Principal attached to site
  +                     Collection principalsForSite = ssoSite.getPrincipals();
  +                     Collection remoteForSite = 
ssoSite.getRemotePrincipals();
  +                     
  +                     // If any of them don't exist just return
  +                     if (principalsForSite == null || remoteForSite== null )
  +                         throw new 
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
                        
  -                     // 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);
  +                     Collection remoteForPrincipals = 
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
  +                     
  +                     if ( remoteForPrincipals == null)
  +                         throw new 
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
  +                     
  +                     // Get remote Principal that matches the site and the 
principal
  +                     if ((remotePrincipal = 
FindRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
  +                     {
  +                         throw new 
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
  +                     }
  +                     
  +                     // Update assocation tables
  +                     ssoSite.getRemotePrincipals().remove(remotePrincipal);
  +                     getRemotePrincipalsForPrincipal(principalsForSite, 
fullPath).remove(remotePrincipal);
  +                 
  +                     // delete the remote Principal from the 
SECURITY_PRINCIPAL table
  +                 getPersistenceBrokerTemplate().delete(remotePrincipal);
                        
                }
                catch(SSOException ssoex)
  @@ -230,7 +279,7 @@
              throw new 
SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
           }
                                                                
  -             // Update database and reset cache
  +             // Update database
                 try
            {
                getPersistenceBrokerTemplate().store(ssoSite);
  @@ -272,15 +321,25 @@
                        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();
  +                     //      Get remotePrincipals for Site and match them 
with the Remote Principal for the Principal attached to site
  +                     Collection principalsForSite = ssoSite.getPrincipals();
  +                     Collection remoteForSite = 
ssoSite.getRemotePrincipals();
  +                     
  +                     // If any of them don't exist just return
  +                     if (principalsForSite == null || remoteForSite== null )
  +                         throw new 
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
  +                     
  +                     Collection remoteForPrincipals = 
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
                        
  +                     if ( remoteForPrincipals == null)
  +                         throw new 
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
  +                     
  +                     // Get remote Principal that matches the site and the 
principal
  +                     if ((remotePrincipal = 
FindRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
  +                     {
  +                         throw new 
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
  +                     }
  +                                             
                        // Update principal information
                        remotePrincipal.setFullPath("/sso/user/"+ principalName 
+ "/" + remoteUser);
                        InternalCredential credential = 
(InternalCredential)remotePrincipal.getCredentials().iterator().next();
  @@ -299,11 +358,7 @@
                         {
                                e.printStackTrace();
                            throw new 
SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
  -                      }
  -                      
  -                      // Clear cache
  -                     // this.mapSite.clear();
  -             
  +                      }                       
            }
        
        /*
  @@ -366,60 +421,43 @@
        private SSOContext  getCredential(SSOSite ssoSite, String fullPath)
        {
                InternalCredential credential = null;
  +             InternalUserPrincipal remotePrincipal = null;
                String remoteUser = null;
                String remoteFullPath = null;
  +             
  +             //      Get remotePrincipals for Site and match them with the 
Remote Principal for the Principal attached to site
  +             Collection principalsForSite = ssoSite.getPrincipals();
  +             Collection remoteForSite = ssoSite.getRemotePrincipals();
  +             
  +             // If any of them don't exist just return
  +             if (principalsForSite == null || remoteForSite== null )
  +                 return null;        // no entry
  +             
  +             Collection remoteForPrincipals = 
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
                                
  -             /* Error checking
  -              * 1) should have at least one principal
  -              * 
  -              * If one of the above fails return null wich means that the 
user doesn't have credentials for that site
  -              */
  -             Collection principals = ssoSite.getPrincipals();
  +             if ( remoteForPrincipals == null)
  +                 return null;        // no entry
                
  -             if ( principals == null )
  +             // Get remote Principal that matches the site and the principal
  +             if ((remotePrincipal = FindRemoteMatch(remoteForPrincipals, 
remoteForSite)) == null )
                {
  -                     return null;
  +                 return null;        // No entry
                }
  -             
  -             // Iterate over the principals and extract the principal id for 
the given full path
  -             SSOPrincipal principal = null;
  -             
  -             Iterator itPrincipals = principals.iterator();
  -             while (itPrincipals.hasNext() && principal == null /*not found 
yet*/)
  +             else
                {
  -                     SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next();
  -                     if (             tmp != null 
  -                             && 
tmp.getFullPath().compareToIgnoreCase(fullPath) == 0
  -                             && tmp.getSiteID() == ssoSite.getSiteId())
  +                 // Has an entry
  +                     if ( remotePrincipal.getCredentials() != null)
  +                             credential = 
(InternalCredential)remotePrincipal.getCredentials().iterator().next();
  +                     
  +                     // Error checking  -- should have a credential at this 
point
  +                     if ( credential == null)
                        {
  -                             // Found it stop iteration
  -                             principal = tmp;
  +                             System.out.println("Warning: Remote User " + 
remotePrincipal.getFullPath() + " doesn't have a credential");
  +                             return null; 
                        }
                }
                
  -             if ( principal == null)
  -                     return null;    // No principal found for that site
  -             
  -             // 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)
  -             {
  -                     System.out.println("Warning: Remote User " + 
remotePrincipal.getFullPath() + " doesn't have a credential");
  -                     return null; 
  -             }
  -             
  -             
  -             // Create new context
  +             //      Create new context
                String name = remotePrincipal.getFullPath();
                int ix = name.lastIndexOf('/');
                if ( ix != -1)
  @@ -479,36 +517,30 @@
                        }
                }
                
  -             // 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 principal;
  +     }
  +     
  +     private SSOPrincipal getSSOPrincipa(String fullPath)
  +     {
  +         // FInd if the principal exists in the SECURITY_PRINCIPAL table
  +         SSOPrincipal 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)
  +         {
  +             Iterator itPrincipals = principals.iterator();
  +             // Get the site from the collection. There should be only one 
entry (uniqueness)
  +             if (itPrincipals.hasNext())
                    {
  -                     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
  -                                     {
  -                                 // Set the Site ID for this principal
  -                                 principal.setSiteID(ssoSite.getSiteId());
  -                                     ssoSite.addPrincipal(principal);
  -                                     }
  -                             catch (SSOException ssoex)
  -                                     {
  -                                     System.out.println("ERROR-SSO: Failed 
adding principal to principla map. Error: " + ssoex.getMessage());
  -                                     }
  -                         }
  +                     principal = (SSOPrincipal) itPrincipals.next();
                    }
  -             }
  -                     
  +         }
  +         
                return principal;               
        }
        
  @@ -572,5 +604,46 @@
                }               
                
                throw new 
SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST);
  +     }
  +     
  +     /*
  +      * 
  +      * 
  +      */
  +     private InternalUserPrincipal FindRemoteMatch(Collection 
remoteForPrincipals, Collection remoteForSite)
  +     {
  +         // Iterate over the lists and find match
  +         Iterator itRemoteForPrincipals = remoteForPrincipals.iterator();
  +         while ( itRemoteForPrincipals.hasNext())
  +         {
  +             InternalUserPrincipal remoteForPrincipal = 
(InternalUserPrincipal)itRemoteForPrincipals.next();
  +             
  +             // Find a match in the site list
  +             Iterator itRemoteForSite = remoteForSite.iterator();
  +                 while ( itRemoteForSite.hasNext())
  +                 {
  +                     InternalUserPrincipal tmp = 
(InternalUserPrincipal)itRemoteForSite.next();
  +                     
  +                     if ( tmp.getPrincipalId() == 
remoteForPrincipal.getPrincipalId() )
  +                         return remoteForPrincipal;
  +                 }
  +         }
  +         // No match found
  +         return null;
  +     }
  +     
  +     private Collection getRemotePrincipalsForPrincipal(Collection 
principalsForSite, String fullPath)
  +     {
  +         if (principalsForSite == null )
  +             return null;
  +         
  +         Iterator itPrincipalsForSite = principalsForSite.iterator();
  +         while (itPrincipalsForSite.hasNext())
  +         {
  +             SSOPrincipal principal = 
(SSOPrincipal)itPrincipalsForSite.next();
  +             if ( principal.getFullPath().compareToIgnoreCase(fullPath) == 0)
  +                 return principal.getRemotePrincipals();
  +         }
  +         return null;
        }
   }
  
  
  
  1.7       +34 -3     
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.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TestSSOComponent.java     4 Dec 2004 05:11:38 -0000       1.6
  +++ TestSSOComponent.java     4 Dec 2004 22:28:19 -0000       1.7
  @@ -49,8 +49,10 @@
         * test url for this UnitTest
         */
        static private String TEST_URL= "http://localhost/jetspeed";;
  +     static private String TEST_URL2= "http://localhost/jetspeed-2";;
        static private String TEST_USER= "joe";
        static private String REMOTE_USER= "remoteJS";
  +     static private String REMOTE_USER2= "remoteJS-2";
        static private String REMOTE_PWD_1 = "remote_1";
        static private String REMOTE_PWD_2 = "remote_2";
        
  @@ -99,11 +101,12 @@
        * Test user root.
        * </p>
        */
  -    public void testSSO() throws Exception
  +  /*  public void testSSO() throws Exception
       {
           // TODO: FIXME: test fails on HSQL Oracle
       }
  -    public void XXXtestSSO() throws Exception
  +    */
  +    public void testSSO() throws Exception
       {
                // Create a user
                 try
  @@ -143,9 +146,37 @@
                System.out.println("SSO Credential found for user:" + 
TEST_USER+ " site: " + TEST_URL);
        }
        
  +     // Add another remote principal for the same user
  +     if ( ssoBroker.hasSSOCredentials(subject, TEST_URL2) == false)
  +     {
  +             System.out.println("No SSO Credential for user:" + TEST_USER+ " 
site: " + TEST_URL2);
  +             
  +             // Add credential
  +             try
  +                     {
  +                     ssoBroker.addCredentialsForSite(subject, REMOTE_USER2, 
TEST_URL2,REMOTE_PWD_1);
  +                     System.out.println("SSO Credential added for user:" + 
TEST_USER+ " site: " + TEST_URL2);
  +                     }
  +                     catch(SSOException ssoex)
  +                     {
  +                     System.out.println("SSO Credential add FAILED for 
user:" + TEST_USER+ " site: " + TEST_URL2);
  +                     ssoex.printStackTrace();
  +                     throw new Exception(ssoex.getMessage());
  +                     }
  +     }
  +     else
  +     {
  +             System.out.println("SSO Credential found for user:" + 
TEST_USER+ " site: " + TEST_URL2);
  +     }
  +     
  +     // Test if the credential where persisted
  +     
        // Test credential update
        SSOContext ssocontext = ssoBroker.getCredentials(subject, TEST_URL);
  -     System.out.println("SSO Credential: User:" + ssocontext.getUserName() + 
" Password: " + ssocontext.getPassword());
  +     System.out.println("SSO Credential: User:" + ssocontext.getUserName() + 
" Password: " + ssocontext.getPassword()+ " for site: " + TEST_URL);
  +     
  +     SSOContext ssocontext2 = ssoBroker.getCredentials(subject, TEST_URL2);
  +     System.out.println("SSO Credential: User:" + ssocontext.getUserName() + 
" Password: " + ssocontext.getPassword() + " for site: " + TEST_URL2);
        
        try
                {
  
  
  
  1.5       +14 -0     
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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- sso_repository.xml        3 Dec 2004 21:59:15 -0000       1.4
  +++ sso_repository.xml        4 Dec 2004 22:28:19 -0000       1.5
  @@ -157,6 +157,20 @@
                <fk-pointing-to-this-class column="SITE_ID"/>
                <fk-pointing-to-element-class column="PRINCIPAL_ID"/>
            </collection-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_SITE_TO_REMOTE"
  +         >
  +             <documentation>This is the reference to 
principals.</documentation>
  +             <fk-pointing-to-this-class column="SITE_ID"/>
  +             <fk-pointing-to-element-class column="PRINCIPAL_ID"/>
  +         </collection-descriptor>
        </class-descriptor>
        
   </descriptor-repository>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to