You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tb...@apache.org on 2006/12/12 16:24:14 UTC
svn commit: r486187 [5/49] - in /directory/trunks/triplesec: ./ admin-api/
admin-api/src/ admin-api/src/main/ admin-api/src/main/java/
admin-api/src/main/java/org/ admin-api/src/main/java/org/safehaus/
admin-api/src/main/java/org/safehaus/triplesec/ ad...
Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapGroupDao.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapGroupDao.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapGroupDao.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapGroupDao.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,404 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.safehaus.triplesec.admin.dao.ldap;
+
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SchemaViolationException;
+import javax.naming.directory.SearchControls;
+
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.safehaus.triplesec.admin.Constants;
+import org.safehaus.triplesec.admin.ConstraintViolationException;
+import org.safehaus.triplesec.admin.DataAccessException;
+import org.safehaus.triplesec.admin.EntryAlreadyExistsException;
+import org.safehaus.triplesec.admin.Group;
+import org.safehaus.triplesec.admin.NoSuchEntryException;
+import org.safehaus.triplesec.admin.dao.GroupDao;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class LdapGroupDao implements GroupDao, LdapDao, Constants
+{
+ private static final Logger log = LoggerFactory.getLogger( LdapGroupDao.class );
+ private static final String[] ATTRIBUTES = {
+ COMMON_NAME_ID, CREATORS_NAME_ID, CREATE_TIMESTAMP_ID, MODIFIERS_NAME_ID, MODIFY_TIMESTAMP_ID, UNIQUE_MEMBER_ID
+ };
+ private final DirContext ctx;
+ private final String baseUrl;
+ private final String principalName;
+
+
+ public LdapGroupDao( DirContext ctx ) throws DataAccessException
+ {
+ this.ctx = ctx;
+ String name = null;
+ String principal = null;
+ try
+ {
+ name = ctx.getNameInNamespace();
+ String principalDn = ( String ) ctx.getEnvironment().get( Context.SECURITY_PRINCIPAL );
+ if ( principalDn.equalsIgnoreCase( "uid=admin,ou=system" ) )
+ {
+ principal = "admin";
+ }
+ else
+ {
+ principal = ( String ) new LdapDN( principalDn ).getRdn().getValue();
+ }
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to get name in namespace for base context.";
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ finally
+ {
+ baseUrl = name;
+ principalName = principal;
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // GroupDao method implementations
+ // -----------------------------------------------------------------------
+
+
+ public Group add( String name, Set members ) throws DataAccessException
+ {
+ if ( members.size() == 0 )
+ {
+ throw new ConstraintViolationException( "At least one member must be present within a group." );
+ }
+
+ BasicAttributes attrs = new BasicAttributes( OBJECT_CLASS_ID, GROUP_OF_UNIQUE_NAMES_OC, true );
+ attrs.put( COMMON_NAME_ID, name );
+ attrs.put( convertToLdapDns( members ) );
+ String rdn = getRelativeDn( name );
+ try
+ {
+ ctx.createSubcontext( rdn, attrs );
+ return new Group( principalName, new Date( System.currentTimeMillis() ), this, name, members );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ log.error( "Cannot create group " + rdn, e );
+ EntryAlreadyExistsException eaee = new EntryAlreadyExistsException();
+ eaee.initCause( e );
+ throw eaee;
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Unexpected failure", e );
+ throw new DataAccessException( e.getMessage() );
+ }
+ }
+
+
+ public Group rename( String newName, Group archetype ) throws DataAccessException
+ {
+ String oldRdn = getRelativeDn( archetype.getName() );
+ String newRdn = getRelativeDn( newName );
+
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Rename failed. Could not find " + oldRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ String msg = "Rename failed. Another group already exists at " + newRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new EntryAlreadyExistsException( msg );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " is required by other entities";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " could not be renamed to " + newRdn;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new Group( archetype.getCreatorsName(), archetype.getCreateTimestamp(), principalName,
+ new Date( System.currentTimeMillis() ), this, newName, archetype.getMembers() );
+ }
+
+
+ public Group modify( String creatorsName, Date createTimestamp, String name, Set members, ModificationItem[] mods )
+ throws DataAccessException
+ {
+ if ( members.size() == 0 )
+ {
+ throw new ConstraintViolationException( "At least one member must be present within a group." );
+ }
+
+ String rdn = getRelativeDn( name );
+ for ( int ii = 0; ii < mods.length; ii++ )
+ {
+ mods[ii] = convertToLdapDns( mods[ii] );
+ }
+
+ try
+ {
+ ctx.modifyAttributes( rdn, mods );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ msg += " The modification violates constraints.";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Entry " + rdn + " under " + baseUrl + " does not exist";
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+
+ return new Group( creatorsName, createTimestamp, this.principalName,
+ new Date( System.currentTimeMillis() ), this, name, members );
+ }
+
+
+ public void delete( String name ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( name );
+
+ try
+ {
+ ctx.destroySubcontext( rdn );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ msg += ". Other entities depend on " + name;
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ public Group load( String name ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( name );
+ Set members = null;
+ Attributes attrs = null;
+ String creatorsName = null;
+ String modifiersName = null;
+ Date createTimestamp = null;
+ Date modifyTimestamp = null;
+
+ try
+ {
+ attrs = ctx.getAttributes( rdn, ATTRIBUTES );
+ members = convertDnsToUsers( attrs.get( UNIQUE_MEMBER_ID ) );
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Could not find " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to lookup " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new Group( creatorsName, createTimestamp, modifiersName, modifyTimestamp, this, name, members );
+ }
+
+
+ public Iterator iterator() throws DataAccessException
+ {
+ String base = "ou=Groups";
+ SearchControls controls = new SearchControls();
+ controls.setReturningAttributes( ATTRIBUTES );
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ try
+ {
+ return new JndiIterator( this, ctx.search( base,
+ "(objectClass=groupOfUniqueNames)", controls ), null );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to search " + base + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Private utility methods
+ // -----------------------------------------------------------------------
+
+
+ private Set convertDnsToUsers( Attribute attribute ) throws NamingException
+ {
+ Set members = new HashSet();
+ for ( int ii = 0; ii < attribute.size(); ii++ )
+ {
+ LdapDN userDn = new LdapDN( ( String ) attribute.get( ii ) );
+ String member = ( String ) userDn.getRdn().getValue();
+ members.add( member );
+ }
+ return members;
+ }
+
+
+ private String getRelativeDn( String name )
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "cn=" ).append( name );
+ buf.append( ",ou=Groups" );
+ return buf.toString();
+ }
+
+
+ private ModificationItem convertToLdapDns( ModificationItem item )
+ {
+ Attribute users = item.getAttribute();
+ BasicAttribute userDns = new BasicAttribute( users.getID() );
+ for ( int ii = 0; ii < users.size(); ii++ )
+ {
+ StringBuffer buf = new StringBuffer();
+ try
+ {
+ buf.append( "uid=" ).append( ( String ) users.get( ii ) );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Could not access attribute value.", e );
+ }
+ buf.append( ",ou=Users," ).append( baseUrl );
+ userDns.add( buf.toString() );
+ }
+
+ return new ModificationItem( item.getModificationOp(), userDns );
+ }
+
+
+ private Attribute convertToLdapDns ( Set members )
+ {
+ BasicAttribute attr = new BasicAttribute( UNIQUE_MEMBER_ID );
+ for ( Iterator ii = members.iterator(); ii.hasNext(); /**/ )
+ {
+ String userId = ( String ) ii.next();
+ StringBuffer buf = new StringBuffer();
+ buf.append( "uid=" ).append( userId );
+ buf.append( ",ou=Users," ).append( baseUrl );
+ attr.add( buf.toString() );
+ }
+ return attr;
+ }
+
+
+ // -----------------------------------------------------------------------
+ // LdapDao method implementations
+ // -----------------------------------------------------------------------
+
+
+ public Object getEntryObject( Object extra, Attributes attrs )
+ {
+ String name = null;
+ Set members = null;
+ String creatorsName = null;
+ String modifiersName = null;
+ Date createTimestamp = null;
+ Date modifyTimestamp = null;
+
+ try
+ {
+ name = ( String ) attrs.get( COMMON_NAME_ID ).get();
+ members = convertDnsToUsers( attrs.get( UNIQUE_MEMBER_ID ) );
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to produce object for attributes: " + attrs;
+ log.error( msg, e );
+ }
+
+ return new Group( creatorsName, createTimestamp, modifiersName, modifyTimestamp, this, name, members );
+ }
+
+
+ public void deleteEntry( String rdn )
+ {
+ try
+ {
+ ctx.destroySubcontext( rdn );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Failed to delete " + rdn + " under " + baseUrl, e );
+ }
+ }
+}
Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapHauskeysUserDao.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapHauskeysUserDao.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapHauskeysUserDao.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapHauskeysUserDao.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,675 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.safehaus.triplesec.admin.dao.ldap;
+
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SchemaViolationException;
+import javax.naming.directory.SearchControls;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.safehaus.triplesec.admin.Constants;
+import org.safehaus.triplesec.admin.ConstraintViolationException;
+import org.safehaus.triplesec.admin.DataAccessException;
+import org.safehaus.triplesec.admin.EntryAlreadyExistsException;
+import org.safehaus.triplesec.admin.HauskeysUser;
+import org.safehaus.triplesec.admin.NoSuchEntryException;
+import org.safehaus.triplesec.admin.PermissionDeniedException;
+import org.safehaus.triplesec.admin.dao.HauskeysUserDao;
+
+
+public class LdapHauskeysUserDao extends AbstractLdapDao implements HauskeysUserDao, Constants
+{
+ private static final String[] ATTRIBUTES = { "*", "+" };
+
+
+ public LdapHauskeysUserDao( DirContext ctx ) throws DataAccessException
+ {
+ super( ctx );
+ }
+
+
+ public HauskeysUser add( String id, String description, String firstName,
+ String lastName, String password, String mobile,
+ String email, String notifyBy, String mobileCarrier, String tokenPin, String midletName,
+ String failuresInEpoch, String activationKey, String realm, String secret, String label,
+ String movingFactor, String address1, String address2,
+ String city, String stateProvRegion, String zipPostalCode,
+ String country, String company, boolean disabled ) throws DataAccessException
+ {
+ StringBuffer buf = new StringBuffer();
+ BasicAttributes attrs = new BasicAttributes( OBJECT_CLASS_ID, "top", true );
+ attrs.get( OBJECT_CLASS_ID ).add( EXTENSIBLE_OBJECT_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( SAFEHAUS_PROFILE_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( UID_OBJECT_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( KRB5KDCENTRY_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( KRB5PRINCIPAL_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( INET_ORG_PERSON_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( PERSON_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( ORGANIZATIONAL_PERSON_OC );
+ attrs.put( UID_ID, id );
+ attrs.put( SAFEHAUS_ID, id );
+ String cn = buf.append( firstName ).append( " " ).append( lastName ).toString();
+ buf.setLength( 0 );
+ attrs.put( COMMON_NAME_ID, cn );
+ attrs.put( GIVENNAME_ID, firstName );
+ attrs.put( SURNAME_ID, lastName );
+ attrs.put( PASSWORD_ID, StringTools.getBytesUtf8( password ) );
+ attrs.put( APACHE_SAM_TYPE_ID, "7" );
+ attrs.put( SAFEHAUS_RESYNCH_COUNT_ID, "-1" );
+
+ if ( tokenPin != null )
+ {
+ attrs.put( TOKEN_PIN_ID, tokenPin );
+ }
+
+ if ( description != null )
+ {
+ attrs.put( DESCRIPTION_ID, description );
+ }
+
+ if ( mobile != null )
+ {
+ attrs.put( MOBILE_ID, mobile );
+ }
+
+ if ( email != null )
+ {
+ attrs.put( EMAIL_ID, email );
+ }
+
+ if ( notifyBy != null )
+ {
+ attrs.put( NOTIFY_BY_ID, notifyBy );
+ }
+
+ if ( mobileCarrier != null )
+ {
+ attrs.put( MOBILE_CARRIER_ID, mobileCarrier );
+ }
+
+ if ( midletName == null )
+ {
+ attrs.put( MIDLE_NAME_ID, this.realm );
+ }
+ else
+ {
+ attrs.put( MIDLE_NAME_ID, midletName );
+ }
+
+ if ( failuresInEpoch == null )
+ {
+ attrs.put( FAILURES_IN_EPOCH_ID, "0" );
+ }
+ else
+ {
+ attrs.put( FAILURES_IN_EPOCH_ID, failuresInEpoch );
+ }
+
+ if ( activationKey != null )
+ {
+ attrs.put( ACTIVATION_KEY_ID, activationKey );
+ }
+
+ if ( realm == null )
+ {
+ attrs.put( REALM_ID, this.realm );
+ }
+ else
+ {
+ attrs.put( REALM_ID, realm );
+ }
+
+ if ( label != null )
+ {
+ attrs.put( LABEL_ID, label );
+ }
+
+ if ( address1 != null )
+ {
+ attrs.put( STREET_ID, address1 );
+ }
+
+ if ( address2 != null )
+ {
+ attrs.put( POSTAL_ADDRESS_ID, address2 );
+ }
+
+ if ( city != null )
+ {
+ attrs.put( LOCALITY_NAME_ID, city );
+ }
+
+ if ( stateProvRegion != null )
+ {
+ attrs.put( STATE_PROVINCE_ID, stateProvRegion );
+ }
+
+ if ( zipPostalCode != null )
+ {
+ attrs.put( ZIP_POSTAL_CODE_ID, zipPostalCode );
+ }
+
+ if ( country != null )
+ {
+ attrs.put( COUNTRY_ID, country );
+ }
+
+ if ( company != null )
+ {
+ attrs.put( ORGANIZATION_ID, company );
+ }
+
+ if ( disabled )
+ {
+ attrs.put( KRB5_DISABLED_ID, "TRUE" );
+ }
+ else
+ {
+ attrs.put( KRB5_DISABLED_ID, "FALSE" );
+ }
+
+ // -------------------------------------------------------------------
+ // Handle HOTP Attributes and Random Generation
+ // -------------------------------------------------------------------
+
+ if ( secret == null )
+ {
+ attrs.put( SECRET_ID, getRandomSecret() );
+ }
+ else
+ {
+ try
+ {
+ attrs.put( SECRET_ID, secret.getBytes( "UTF-8" ) );
+ }
+ catch ( UnsupportedEncodingException e )
+ {
+ throw new RuntimeException( "Failed to decode UTF-8 encoding: " + e.getMessage() );
+ }
+ }
+
+ if ( movingFactor == null )
+ {
+ attrs.put( MOVING_FACTOR_ID, getRandomFactor() );
+ }
+ else
+ {
+ attrs.put( MOVING_FACTOR_ID, movingFactor );
+ }
+
+ // -------------------------------------------------------------------
+ // Handle Kerberos Attributes and Key Encryption
+ // -------------------------------------------------------------------
+
+ String krb5PrincipalName = buf.append( id ).append( "@" ).append( this.realm.toUpperCase() ).toString();
+ buf.setLength( 0 );
+ attrs.put( KRB5PRINCIPAL_NAME_ID, krb5PrincipalName );
+ attrs.put( KRB5PRINCIPAL_REALM_ID, this.realm.toUpperCase() );
+
+ KerberosPrincipal kerberosPrincipal = new KerberosPrincipal( krb5PrincipalName );
+ KerberosKey key = new KerberosKey( kerberosPrincipal, password.toCharArray(), "DES" );
+ byte[] encodedKey = key.getEncoded();
+ attrs.put( KRB5KEY_ID, encodedKey );
+ attrs.put( KRB5KEY_VERSION_NUMBER_ID, Integer.toString( key.getVersionNumber() ) );
+ attrs.put( KRB5ENCRYPTION_TYPE_ID, Integer.toString( key.getKeyType() ) );
+
+ String rdn = getRelativeDn( id );
+ try
+ {
+ ctx.createSubcontext( rdn, attrs );
+ return new HauskeysUser( principalName, new Date( System.currentTimeMillis() ), this,
+ id, description, firstName, lastName, password, mobile, email, notifyBy,
+ mobileCarrier, tokenPin, midletName, failuresInEpoch, activationKey,
+ realm, secret, label, movingFactor, address1, address2, city,
+ stateProvRegion, zipPostalCode, country, company, disabled );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ log.error( "Cannot create hauskeys user " + rdn, e );
+ EntryAlreadyExistsException eaee = new EntryAlreadyExistsException();
+ eaee.initCause( e );
+ throw eaee;
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Unexpected failure", e );
+ throw new DataAccessException( e.getMessage() );
+ }
+ }
+
+
+ public HauskeysUser rename( String newId, HauskeysUser archetype ) throws DataAccessException
+ {
+ String oldRdn = getRelativeDn( archetype.getId() );
+ String newRdn = getRelativeDn( newId );
+
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Rename failed. Could not find " + oldRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ String msg = "Rename failed. Another group already exists at " + newRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new EntryAlreadyExistsException( msg );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " is required by other entities";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NoPermissionException e )
+ {
+ String msg = "Rename failed. Permission denied.";
+ log.error( msg, e );
+ throw new PermissionDeniedException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " could not be renamed to " + newRdn;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ // -------------------------------------------------------------------
+ // Regenerate principal name and key since key depends on principal name
+ // -------------------------------------------------------------------
+
+ StringBuffer buf = new StringBuffer();
+ BasicAttributes attrs = new BasicAttributes( true );
+ String krb5PrincipalName = buf.append( newId ).append( "@" ).append( realm.toUpperCase() ).toString();
+ buf.setLength( 0 );
+ attrs.put( KRB5PRINCIPAL_NAME_ID, krb5PrincipalName );
+ attrs.put( SAFEHAUS_ID, newId );
+
+ KerberosPrincipal kerberosPrincipal = new KerberosPrincipal( krb5PrincipalName );
+ KerberosKey key = new KerberosKey( kerberosPrincipal, archetype.getPassword().toCharArray(), "DES" );
+ byte[] encodedKey = key.getEncoded();
+ attrs.put( KRB5KEY_ID, encodedKey );
+
+ try
+ {
+ ctx.modifyAttributes( newRdn, DirContext.REPLACE_ATTRIBUTE, attrs );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Rename partially failed. Could not update kerberos key and principal name for " + newRdn;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new HauskeysUser( archetype.getCreatorsName(), archetype.getCreateTimestamp(),
+ principalName, new Date( System.currentTimeMillis() ), this, newId,
+ archetype.getDescription(), archetype.getFirstName(),
+ archetype.getLastName(), archetype.getPassword(), archetype.getMobile(), archetype.getEmail(),
+ archetype.getNotifyBy(), archetype.getMobileCarrier(), archetype.getTokenPin(),
+ archetype.getMidletName(), archetype.getFailuresInEpoch(), archetype.getActivationKey(),
+ archetype.getRealm(), archetype.getSecret(), archetype.getLabel(), archetype.getMovingFactor(),
+ archetype.getAddress1(), archetype.getAddress2(), archetype.getCity(),
+ archetype.getStateProvRegion(), archetype.getZipPostalCode(), archetype.getCountry(),
+ archetype.getCompany(), archetype.isDisabled() );
+ }
+
+
+ public HauskeysUser modify( String creatorsName, Date createTimestamp, String id,
+ String description, String firstName, String lastName, String password, String mobile,
+ String email, String notifyBy, String mobileCarrier, String tokenPin, String midletName,
+ String failuresInEpoch, String activationKey, String realm, String secret, String label,
+ String movingFactor, String address1, String address2, String city,
+ String stateProvRegion, String zipPostalCode, String country, String company,
+ boolean disabled, ModificationItem[] mods ) throws DataAccessException
+ {
+ for ( int ii = 0; ii < mods.length; ii++ )
+ {
+ if ( mods[ii].getAttribute().getID().equalsIgnoreCase( "userPassword" ) )
+ {
+ StringBuffer buf = new StringBuffer();
+ String krb5PrincipalName = buf.append( id ).append( "@" ).append( realm.toUpperCase() ).toString();
+ KerberosPrincipal kerberosPrincipal = new KerberosPrincipal( krb5PrincipalName );
+ KerberosKey key = new KerberosKey( kerberosPrincipal, password.toCharArray(), "DES" );
+ byte[] encodedKey = key.getEncoded();
+ Attribute attr = new BasicAttribute( KRB5KEY_ID, encodedKey );
+ ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+ ModificationItem[] temp = mods;
+ mods = new ModificationItem[temp.length + 1];
+ for ( int jj = 0; jj < temp.length; jj++ )
+ {
+ mods[jj] = temp[jj];
+ }
+ mods[temp.length] = item;
+ }
+ }
+
+ String rdn = getRelativeDn( id );
+ try
+ {
+ ctx.modifyAttributes( rdn, mods );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ msg += " The modification violates constraints.";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Entry " + rdn + " under " + baseUrl + " does not exist";
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NoPermissionException e )
+ {
+ String msg = "Modify failed. Permission denied to " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new PermissionDeniedException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+
+ return new HauskeysUser( creatorsName, createTimestamp, this.principalName,
+ new Date( System.currentTimeMillis() ), this, id, description, firstName, lastName,
+ password, mobile, email, notifyBy, mobileCarrier, tokenPin, midletName, failuresInEpoch,
+ activationKey, realm, secret, label, movingFactor, address1, address2, city,
+ stateProvRegion, zipPostalCode, country, company, disabled );
+ }
+
+
+ public void delete( String id ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( id );
+
+ try
+ {
+ ctx.destroySubcontext( rdn );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ msg += ". Other entities depend on " + id;
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NoPermissionException e )
+ {
+ String msg = "Delete failed. Permission denied to delete " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new PermissionDeniedException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ public HauskeysUser load( String id ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( id );
+ Attributes attrs = null;
+ String description = null;
+ String password = null;
+ String firstName = null;
+ String lastName = null;
+ String creatorsName = null;
+ String modifiersName = null;
+ Date createTimestamp = null;
+ Date modifyTimestamp = null;
+ String mobile = null;
+ String email = null;
+ String notifyBy = null;
+ String mobileCarrier = null;
+ String tokenPin = null;
+ String midletName = null;
+ String failuresInEpoch = null;
+ String activationKey = null;
+ String realm = null;
+ String secret = null;
+ String label = null;
+ String movingFactor = null;
+ String address1 = null;
+ String address2 = null;
+ String city = null;
+ String stateProvRegion = null;
+ String zipPostalCode = null;
+ String country = null;
+ String company = null;
+ boolean disabled = false;
+
+ try
+ {
+ attrs = ctx.getAttributes( rdn, ATTRIBUTES );
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ description = LdapUtils.getSingleValued( DESCRIPTION_ID, attrs );
+ lastName = ( String ) attrs.get( SURNAME_ID ).get();
+ firstName = LdapUtils.getSingleValued( GIVENNAME_ID, attrs );
+ password = LdapUtils.getSingleValued( PASSWORD_ID, attrs );
+ disabled = LdapUtils.getBoolean( KRB5_DISABLED_ID, attrs, false );
+
+ mobile = LdapUtils.getSingleValued( MOBILE_ID, attrs );
+ email = LdapUtils.getSingleValued( EMAIL_ID, attrs );
+ notifyBy = LdapUtils.getSingleValued( NOTIFY_BY_ID, attrs );
+ mobileCarrier = LdapUtils.getSingleValued( MOBILE_CARRIER_ID, attrs );
+ tokenPin = LdapUtils.getSingleValued( TOKEN_PIN_ID, attrs );
+ midletName = LdapUtils.getSingleValued( MIDLE_NAME_ID, attrs );
+ failuresInEpoch = LdapUtils.getSingleValued( FAILURES_IN_EPOCH_ID, attrs );
+ activationKey = LdapUtils.getSingleValued( ACTIVATION_KEY_ID, attrs );
+ realm = LdapUtils.getSingleValued( REALM_ID , attrs );
+ secret = LdapUtils.getSingleValued( SECRET_ID, attrs );
+ label = LdapUtils.getSingleValued( LABEL_ID, attrs );
+ movingFactor = LdapUtils.getSingleValued( MOVING_FACTOR_ID, attrs );
+
+ address1 = LdapUtils.getSingleValued( STREET_ID, attrs );
+ address2 = LdapUtils.getSingleValued( POSTAL_ADDRESS_ID, attrs );
+ city = LdapUtils.getSingleValued( LOCALITY_NAME_ID, attrs );
+ stateProvRegion = LdapUtils.getSingleValued( STATE_PROVINCE_ID, attrs );
+ zipPostalCode = LdapUtils.getSingleValued( ZIP_POSTAL_CODE_ID, attrs );
+ country = LdapUtils.getSingleValued( COUNTRY_ID, attrs );
+ company = LdapUtils.getSingleValued( ORGANIZATION_ID, attrs );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Could not find " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to lookup " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new HauskeysUser( creatorsName, createTimestamp, modifiersName, modifyTimestamp,
+ this, id, description, firstName, lastName, password, mobile, email, notifyBy,
+ mobileCarrier, tokenPin, midletName, failuresInEpoch, activationKey, realm,
+ secret, label, movingFactor, address1, address2, city, stateProvRegion,
+ zipPostalCode, country, company, disabled );
+ }
+
+
+ public Iterator iterator() throws DataAccessException
+ {
+ String base = "ou=Users";
+ SearchControls controls = new SearchControls();
+ controls.setReturningAttributes( ATTRIBUTES );
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ try
+ {
+ return new JndiIterator( this, ctx.search( base,
+ "(& (objectClass=safehausProfile) (apacheSamType=*) )", controls ), null );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to search " + base + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ public Object getEntryObject( Object extra, Attributes attrs )
+ {
+ String uid = null;
+ String description = null;
+ String password = null;
+ String firstName = null;
+ String lastName = null;
+ String creatorsName = null;
+ String modifiersName = null;
+ Date createTimestamp = null;
+ Date modifyTimestamp = null;
+ String mobile = null;
+ String email = null;
+ String notifyBy = null;
+ String mobileCarrier = null;
+ String tokenPin = null;
+ String midletName = null;
+ String failuresInEpoch = null;
+ String activationKey = null;
+ String realm = null;
+ String secret = null;
+ String label = null;
+ String movingFactor = null;
+ String address1 = null;
+ String address2 = null;
+ String city = null;
+ String stateProvRegion = null;
+ String zipPostalCode = null;
+ String country = null;
+ String company = null;
+ boolean disabled = false;
+
+ try
+ {
+ uid = ( String ) attrs.get( UID_ID ).get();
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ description = LdapUtils.getSingleValued( DESCRIPTION_ID, attrs );
+ lastName = ( String ) attrs.get( SURNAME_ID ).get();
+ firstName = LdapUtils.getSingleValued( GIVENNAME_ID, attrs );
+ password = LdapUtils.getSingleValued( PASSWORD_ID, attrs );
+ disabled = LdapUtils.getBoolean( KRB5_DISABLED_ID, attrs, false );
+
+ mobile = LdapUtils.getSingleValued( MOBILE_ID, attrs );
+ email = LdapUtils.getSingleValued( EMAIL_ID, attrs );
+ notifyBy = LdapUtils.getSingleValued( NOTIFY_BY_ID, attrs );
+ mobileCarrier = LdapUtils.getSingleValued( MOBILE_CARRIER_ID, attrs );
+ tokenPin = LdapUtils.getSingleValued( TOKEN_PIN_ID, attrs );
+ midletName = LdapUtils.getSingleValued( MIDLE_NAME_ID, attrs );
+ failuresInEpoch = LdapUtils.getSingleValued( FAILURES_IN_EPOCH_ID, attrs );
+ activationKey = LdapUtils.getSingleValued( ACTIVATION_KEY_ID, attrs );
+ realm = LdapUtils.getSingleValued( REALM_ID , attrs );
+ secret = LdapUtils.getSingleValued( SECRET_ID, attrs );
+ label = LdapUtils.getSingleValued( LABEL_ID, attrs );
+ movingFactor = LdapUtils.getSingleValued( MOVING_FACTOR_ID, attrs );
+
+ address1 = LdapUtils.getSingleValued( STREET_ID, attrs );
+ address2 = LdapUtils.getSingleValued( POSTAL_ADDRESS_ID, attrs );
+ city = LdapUtils.getSingleValued( LOCALITY_NAME_ID, attrs );
+ stateProvRegion = LdapUtils.getSingleValued( STATE_PROVINCE_ID, attrs );
+ zipPostalCode = LdapUtils.getSingleValued( ZIP_POSTAL_CODE_ID, attrs );
+ country = LdapUtils.getSingleValued( COUNTRY_ID, attrs );
+ company = LdapUtils.getSingleValued( ORGANIZATION_ID, attrs );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to produce object for attributes: " + attrs;
+ log.error( msg, e );
+ }
+
+ return new HauskeysUser( creatorsName, createTimestamp, modifiersName, modifyTimestamp,
+ this, uid, description, firstName, lastName, password, mobile, email, notifyBy,
+ mobileCarrier, tokenPin, midletName, failuresInEpoch, activationKey, realm,
+ secret, label, movingFactor, address1, address2, city, stateProvRegion,
+ zipPostalCode, country, company, disabled );
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Private Utility Methods
+ // -----------------------------------------------------------------------
+
+
+ private String getRelativeDn( String uid )
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "uid=" ).append( uid );
+ buf.append( ",ou=Users" );
+ return buf.toString();
+ }
+
+
+ private String getRandomFactor()
+ {
+ return String.valueOf( RandomUtils.nextLong() );
+ }
+
+
+ private byte[] getRandomSecret()
+ {
+ // max length 16, min length 8 bytes
+ int length = 8 + RandomUtils.nextInt() % 8;
+ try
+ {
+ return RandomStringUtils.random( length ).getBytes( "UTF-8" );
+ }
+ catch ( UnsupportedEncodingException e )
+ {
+ throw new RuntimeException( "Failed to decode UTF-8 encoding: " + e.getMessage() );
+ }
+ }
+}
Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapLocalUserDao.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapLocalUserDao.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapLocalUserDao.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapLocalUserDao.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,504 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.safehaus.triplesec.admin.dao.ldap;
+
+
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SchemaViolationException;
+import javax.naming.directory.SearchControls;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import org.apache.directory.shared.ldap.util.StringTools;
+
+import org.safehaus.triplesec.admin.Constants;
+import org.safehaus.triplesec.admin.ConstraintViolationException;
+import org.safehaus.triplesec.admin.DataAccessException;
+import org.safehaus.triplesec.admin.EntryAlreadyExistsException;
+import org.safehaus.triplesec.admin.LocalUser;
+import org.safehaus.triplesec.admin.NoSuchEntryException;
+import org.safehaus.triplesec.admin.PermissionDeniedException;
+import org.safehaus.triplesec.admin.dao.LocalUserDao;
+
+
+public class LdapLocalUserDao extends AbstractLdapDao implements LocalUserDao, Constants
+{
+ private static final String[] ATTRIBUTES = { "*", "+" };
+
+
+ public LdapLocalUserDao( DirContext ctx ) throws DataAccessException
+ {
+ super( ctx );
+ }
+
+
+ public LocalUser add( String id, String description, String firstName,
+ String lastName, String password, String address1, String address2,
+ String city, String stateProvRegion, String zipPostalCode,
+ String country, String company, String email, boolean disabled ) throws DataAccessException
+ {
+ StringBuffer buf = new StringBuffer();
+ BasicAttributes attrs = new BasicAttributes( OBJECT_CLASS_ID, "top", true );
+ attrs.get( OBJECT_CLASS_ID ).add( EXTENSIBLE_OBJECT_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( UID_OBJECT_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( KRB5KDCENTRY_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( KRB5PRINCIPAL_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( INET_ORG_PERSON_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( PERSON_OC );
+ attrs.get( OBJECT_CLASS_ID ).add( ORGANIZATIONAL_PERSON_OC );
+ attrs.put( UID_ID, id );
+ String cn = buf.append( firstName ).append( " " ).append( lastName ).toString();
+ buf.setLength( 0 );
+ attrs.put( COMMON_NAME_ID, cn );
+ attrs.put( GIVENNAME_ID, firstName );
+ attrs.put( SURNAME_ID, lastName );
+ attrs.put( PASSWORD_ID, StringTools.getBytesUtf8( password ) );
+
+ if ( email != null )
+ {
+ attrs.put( EMAIL_ID, email );
+ }
+
+ if ( description != null )
+ {
+ attrs.put( DESCRIPTION_ID, description );
+ }
+
+ if ( address1 != null )
+ {
+ attrs.put( STREET_ID, address1 );
+ }
+
+ if ( address2 != null )
+ {
+ attrs.put( POSTAL_ADDRESS_ID, address2 );
+ }
+
+ if ( city != null )
+ {
+ attrs.put( LOCALITY_NAME_ID, city );
+ }
+
+ if ( stateProvRegion != null )
+ {
+ attrs.put( STATE_PROVINCE_ID, stateProvRegion );
+ }
+
+ if ( zipPostalCode != null )
+ {
+ attrs.put( ZIP_POSTAL_CODE_ID, zipPostalCode );
+ }
+
+ if ( country != null )
+ {
+ attrs.put( COUNTRY_ID, country );
+ }
+
+ if ( company != null )
+ {
+ attrs.put( ORGANIZATION_ID, company );
+ }
+
+ if ( disabled )
+ {
+ attrs.put( KRB5_DISABLED_ID, "TRUE" );
+ }
+ else
+ {
+ attrs.put( KRB5_DISABLED_ID, "FALSE" );
+ }
+
+ // -------------------------------------------------------------------
+ // Handle Kerberos Attributes and Key Encryption
+ // -------------------------------------------------------------------
+
+ String krb5PrincipalName = buf.append( id ).append( "@" ).append( realm.toUpperCase() ).toString();
+ buf.setLength( 0 );
+ attrs.put( KRB5PRINCIPAL_NAME_ID, krb5PrincipalName );
+ attrs.put( KRB5PRINCIPAL_REALM_ID, realm.toUpperCase() );
+
+ KerberosPrincipal kerberosPrincipal = new KerberosPrincipal( krb5PrincipalName );
+ KerberosKey key = new KerberosKey( kerberosPrincipal, password.toCharArray(), "DES" );
+ byte[] encodedKey = key.getEncoded();
+ attrs.put( KRB5KEY_ID, encodedKey );
+ attrs.put( KRB5KEY_VERSION_NUMBER_ID, Integer.toString( key.getVersionNumber() ) );
+ attrs.put( KRB5ENCRYPTION_TYPE_ID, Integer.toString( key.getKeyType() ) );
+
+ String rdn = getRelativeDn( id );
+ try
+ {
+ ctx.createSubcontext( rdn, attrs );
+ return new LocalUser( principalName, new Date( System.currentTimeMillis() ), this,
+ id, description, firstName, lastName, password, address1, address2, city,
+ stateProvRegion, zipPostalCode, country, company, email, disabled );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ log.error( "Cannot create local user " + rdn, e );
+ EntryAlreadyExistsException eaee = new EntryAlreadyExistsException();
+ eaee.initCause( e );
+ throw eaee;
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Unexpected failure", e );
+ throw new DataAccessException( e.getMessage() );
+ }
+ }
+
+
+ public LocalUser rename( String newId, LocalUser archetype ) throws DataAccessException
+ {
+ String oldRdn = getRelativeDn( archetype.getId() );
+ String newRdn = getRelativeDn( newId );
+
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Rename failed. Could not find " + oldRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ String msg = "Rename failed. Another user already exists at " + newRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new EntryAlreadyExistsException( msg );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " is required by other entities";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NoPermissionException e )
+ {
+ String msg = "Rename failed. Permission denied.";
+ log.error( msg, e );
+ throw new PermissionDeniedException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " could not be renamed to " + newRdn;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ // -------------------------------------------------------------------
+ // Regenerate principal name and key since key depends on principal name
+ // -------------------------------------------------------------------
+
+ StringBuffer buf = new StringBuffer();
+ BasicAttributes attrs = new BasicAttributes( true );
+ String krb5PrincipalName = buf.append( newId ).append( "@" ).append( realm.toUpperCase() ).toString();
+ buf.setLength( 0 );
+ attrs.put( KRB5PRINCIPAL_NAME_ID, krb5PrincipalName );
+ attrs.put( SAFEHAUS_ID, newId );
+
+ KerberosPrincipal kerberosPrincipal = new KerberosPrincipal( krb5PrincipalName );
+ KerberosKey key = new KerberosKey( kerberosPrincipal, archetype.getPassword().toCharArray(), "DES" );
+ byte[] encodedKey = key.getEncoded();
+ attrs.put( KRB5KEY_ID, encodedKey );
+
+ try
+ {
+ ctx.modifyAttributes( newRdn, DirContext.REPLACE_ATTRIBUTE, attrs );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Rename partially failed. Could not update kerberos key and principal name for " + newRdn;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new LocalUser( archetype.getCreatorsName(), archetype.getCreateTimestamp(),
+ principalName, new Date( System.currentTimeMillis() ), this, newId,
+ archetype.getDescription(), archetype.getFirstName(), archetype.getLastName(), archetype.getPassword(),
+ archetype.getAddress1(), archetype.getAddress2(), archetype.getCity(),
+ archetype.getStateProvRegion(), archetype.getZipPostalCode(), archetype.getCountry(),
+ archetype.getCompany(), archetype.getEmail(), archetype.isDisabled() );
+ }
+
+
+ public LocalUser modify( String creatorsName, Date createTimestamp, String id, String description,
+ String password, String firstName, String lastName, String address1, String address2, String city,
+ String stateProvRegion, String zipPostalCode, String country, String company, String email,
+ boolean disabled, ModificationItem[] mods ) throws DataAccessException
+ {
+ for ( int ii = 0; ii < mods.length; ii++ )
+ {
+ if ( mods[ii].getAttribute().getID().equalsIgnoreCase( "userPassword" ) )
+ {
+ StringBuffer buf = new StringBuffer();
+ String krb5PrincipalName = buf.append( id ).append( "@" ).append( realm.toUpperCase() ).toString();
+ KerberosPrincipal kerberosPrincipal = new KerberosPrincipal( krb5PrincipalName );
+ KerberosKey key = new KerberosKey( kerberosPrincipal, password.toCharArray(), "DES" );
+ byte[] encodedKey = key.getEncoded();
+ Attribute attr = new BasicAttribute( KRB5KEY_ID, encodedKey );
+ ModificationItem item = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr );
+ ModificationItem[] temp = mods;
+ mods = new ModificationItem[temp.length + 1];
+ for ( int jj = 0; jj < temp.length; jj++ )
+ {
+ mods[jj] = temp[jj];
+ }
+ mods[temp.length] = item;
+ }
+ }
+
+ String rdn = getRelativeDn( id );
+ try
+ {
+ ctx.modifyAttributes( rdn, mods );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ msg += " The modification violates constraints.";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Entry " + rdn + " under " + baseUrl + " does not exist";
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NoPermissionException e )
+ {
+ String msg = "Modify failed. Permission denied to " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new PermissionDeniedException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+
+ return new LocalUser( creatorsName, createTimestamp, this.principalName,
+ new Date( System.currentTimeMillis() ), this, id, description,
+ firstName, lastName, password, address1, address2, city, stateProvRegion,
+ zipPostalCode, country, company, email, disabled );
+ }
+
+
+ public void delete( String id ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( id );
+
+ try
+ {
+ ctx.destroySubcontext( rdn );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ msg += ". Other entities depend on " + id;
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NoPermissionException e )
+ {
+ String msg = "Delete failed. Permission denied to delete " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new PermissionDeniedException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ public LocalUser load( String id ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( id );
+ Attributes attrs = null;
+ String description = null;
+ String password = null;
+ String firstName = null;
+ String lastName = null;
+ String creatorsName = null;
+ String modifiersName = null;
+ String address1 = null;
+ String address2 = null;
+ String city = null;
+ String stateProvRegion = null;
+ String zipPostalCode = null;
+ String country = null;
+ String company = null;
+ String email = null;
+ Date createTimestamp = null;
+ Date modifyTimestamp = null;
+ boolean disabled = false;
+
+ try
+ {
+ attrs = ctx.getAttributes( rdn, ATTRIBUTES );
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ description = LdapUtils.getSingleValued( DESCRIPTION_ID, attrs );
+ lastName = ( String ) attrs.get( SURNAME_ID ).get();
+ firstName = LdapUtils.getSingleValued( GIVENNAME_ID, attrs );
+ password = LdapUtils.getSingleValued( PASSWORD_ID, attrs );
+ disabled = LdapUtils.getBoolean( KRB5_DISABLED_ID, attrs, false );
+
+ address1 = LdapUtils.getSingleValued( STREET_ID, attrs );
+ address2 = LdapUtils.getSingleValued( POSTAL_ADDRESS_ID, attrs );
+ city = LdapUtils.getSingleValued( LOCALITY_NAME_ID, attrs );
+ stateProvRegion = LdapUtils.getSingleValued( STATE_PROVINCE_ID, attrs );
+ zipPostalCode = LdapUtils.getSingleValued( ZIP_POSTAL_CODE_ID, attrs );
+ country = LdapUtils.getSingleValued( COUNTRY_ID, attrs );
+ company = LdapUtils.getSingleValued( ORGANIZATION_ID, attrs );
+ email = LdapUtils.getSingleValued( EMAIL_ID, attrs );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Could not find " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to lookup " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new LocalUser( creatorsName, createTimestamp, modifiersName, modifyTimestamp,
+ this, id, description, firstName, lastName, password, address1, address2, city, stateProvRegion,
+ zipPostalCode, country, company, email, disabled );
+ }
+
+
+ public Iterator iterator() throws DataAccessException
+ {
+ String base = "ou=Users";
+ SearchControls controls = new SearchControls();
+ controls.setReturningAttributes( ATTRIBUTES );
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ try
+ {
+ return new JndiIterator( this, ctx.search( base,
+ "( & (! (apacheSamType=*) ) (objectClass=person) )", controls ), null );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to search " + base + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Private Utility Methods
+ // -----------------------------------------------------------------------
+
+
+ private String getRelativeDn( String uid )
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "uid=" ).append( uid );
+ buf.append( ",ou=Users" );
+ return buf.toString();
+ }
+
+
+ // -----------------------------------------------------------------------
+ // LdapDao method implementations
+ // -----------------------------------------------------------------------
+
+
+ public Object getEntryObject( Object extra, Attributes attrs )
+ {
+ String uid = null;
+ String description = null;
+ String firstName = null;
+ String lastName = null;
+ String password = null;
+ String creatorsName = null;
+ String modifiersName = null;
+ String address1 = null;
+ String address2 = null;
+ String city = null;
+ String stateProvRegion = null;
+ String zipPostalCode = null;
+ String country = null;
+ String company = null;
+ String email = null;
+ Date createTimestamp = null;
+ Date modifyTimestamp = null;
+ boolean disabled = false;
+
+ try
+ {
+ uid = ( String ) attrs.get( UID_ID ).get();
+ lastName = ( String ) attrs.get( SURNAME_ID ).get();
+ firstName = LdapUtils.getSingleValued( GIVENNAME_ID, attrs );
+ description = LdapUtils.getSingleValued( DESCRIPTION_ID, attrs );
+ password = LdapUtils.getSingleValued( PASSWORD_ID, attrs );
+ disabled = LdapUtils.getBoolean( KRB5_DISABLED_ID, attrs, false );
+ address1 = LdapUtils.getSingleValued( STREET_ID, attrs );
+ address2 = LdapUtils.getSingleValued( POSTAL_ADDRESS_ID, attrs );
+ city = LdapUtils.getSingleValued( LOCALITY_NAME_ID, attrs );
+ stateProvRegion = LdapUtils.getSingleValued( STATE_PROVINCE_ID, attrs );
+ zipPostalCode = LdapUtils.getSingleValued( ZIP_POSTAL_CODE_ID, attrs );
+ country = LdapUtils.getSingleValued( COUNTRY_ID, attrs );
+ company = LdapUtils.getSingleValued( ORGANIZATION_ID, attrs );
+ email = LdapUtils.getSingleValued( EMAIL_ID, attrs );
+
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to produce object for attributes: " + attrs;
+ log.error( msg, e );
+ }
+
+ return new LocalUser( creatorsName, createTimestamp, modifiersName, modifyTimestamp,
+ this, uid, description, firstName, lastName, password, address1, address2, city,
+ stateProvRegion, zipPostalCode, country, company, email, disabled );
+ }
+}
Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapPermissionDao.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapPermissionDao.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapPermissionDao.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/dao/ldap/LdapPermissionDao.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,399 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.safehaus.triplesec.admin.dao.ldap;
+
+
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.naming.Context;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SchemaViolationException;
+import javax.naming.directory.SearchControls;
+
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.safehaus.triplesec.admin.Constants;
+import org.safehaus.triplesec.admin.ConstraintViolationException;
+import org.safehaus.triplesec.admin.DataAccessException;
+import org.safehaus.triplesec.admin.EntryAlreadyExistsException;
+import org.safehaus.triplesec.admin.NoSuchEntryException;
+import org.safehaus.triplesec.admin.Permission;
+import org.safehaus.triplesec.admin.dao.PermissionDao;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class LdapPermissionDao implements PermissionDao, LdapDao, Constants
+{
+ public static final String[] ATTRIBUTES = new String[] {
+ DESCRIPTION_ID, PERM_NAME_ID, "creatorsName", "createTimestamp", "modifiersName", "modifyTimestamp"
+ };
+ private static final Logger log = LoggerFactory.getLogger( LdapPermissionDao.class );
+ private final DirContext ctx;
+ private final String baseUrl;
+ private final String principalName;
+
+
+ public LdapPermissionDao( DirContext ctx ) throws DataAccessException
+ {
+ this.ctx = ctx;
+
+ String name = null;
+ String principal = null;
+ try
+ {
+ name = ctx.getNameInNamespace();
+ String principalDn = ( String ) ctx.getEnvironment().get( Context.SECURITY_PRINCIPAL );
+ if ( principalDn.equalsIgnoreCase( "uid=admin,ou=system" ) )
+ {
+ principal = "admin";
+ }
+ else
+ {
+ principal = ( String ) new LdapDN( principalDn ).getRdn().getValue();
+ }
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to get name in namespace for base context.";
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+
+ }
+ finally
+ {
+ baseUrl = name;
+ principalName = principal;
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // PermissionDao method implementations
+ // -----------------------------------------------------------------------
+
+
+ public Permission add( String appName, String permName, String description )
+ throws DataAccessException
+ {
+ BasicAttributes attrs = new BasicAttributes( OBJECT_CLASS_ID, POLICY_PERMISSION_OC, true );
+ attrs.put( PERM_NAME_ID, permName );
+ if ( description != null )
+ {
+ attrs.put( DESCRIPTION_ID, description );
+ }
+
+ String rdn = getRelativeDn( appName, permName );
+ try
+ {
+ ctx.createSubcontext( rdn, attrs );
+ return new Permission( principalName, new Date( System.currentTimeMillis() ),
+ this, appName, permName, description );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ log.error( "Cannot create permission " + rdn, e );
+ EntryAlreadyExistsException eaee = new EntryAlreadyExistsException();
+ eaee.initCause( e );
+ throw eaee;
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Unexpected failure", e );
+ throw new DataAccessException( e.getMessage() );
+ }
+ }
+
+
+ public void delete( String appName, String permName )
+ throws DataAccessException
+ {
+ String rdn = getRelativeDn( appName, permName );
+
+ try
+ {
+ ctx.destroySubcontext( rdn );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ msg += ". Other entities depend on " + permName;
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not delete " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ public Permission modify( String creatorsName, Date createTimestamp, String appName,
+ String permName, String description, ModificationItem[] mods ) throws DataAccessException
+ {
+ String rdn = getRelativeDn( appName, permName );
+
+ try
+ {
+ ctx.modifyAttributes( rdn, mods );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ msg += " The modification violates constraints.";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Entry " + rdn + " under " + baseUrl + " does not exist";
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Could not modify " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+
+ return new Permission( creatorsName, createTimestamp, this.principalName,
+ new Date( System.currentTimeMillis() ), this, appName, permName, description );
+ }
+
+
+ public Permission rename( String newPermName, Permission perm )
+ throws DataAccessException
+ {
+ String oldRdn = getRelativeDn( perm.getApplicationName(), perm.getName() );
+ String newRdn = getRelativeDn( perm.getApplicationName(), newPermName );
+
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Rename failed. Could not find " + oldRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NameAlreadyBoundException e )
+ {
+ String msg = "Rename failed. Another permission already exists at " + newRdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new EntryAlreadyExistsException( msg );
+ }
+ catch ( SchemaViolationException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " is required by other entities";
+ log.error( msg, e );
+ throw new ConstraintViolationException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Rename failed. " + oldRdn + " under " + baseUrl + " could not be renamed to " + newRdn;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new Permission( perm.getCreatorsName(), perm.getCreateTimestamp(), principalName,
+ new Date( System.currentTimeMillis() ),
+ this, perm.getApplicationName(), newPermName, perm.getDescription() );
+ }
+
+
+ public Permission load( String appName, String permName )
+ throws DataAccessException
+ {
+ String description = null;
+ String creatorsName = null;
+ Date createTimestamp = null;
+ String modifiersName = null;
+ Date modifyTimestamp = null;
+ String rdn = getRelativeDn( appName, permName );
+ Attributes attrs = null;
+
+ try
+ {
+ attrs = ctx.getAttributes( rdn, ATTRIBUTES );
+ description = LdapUtils.getSingleValued( DESCRIPTION_ID, attrs );
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ }
+ catch ( NameNotFoundException e )
+ {
+ String msg = "Could not find " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new NoSuchEntryException( msg );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to lookup " + rdn + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+
+ return new Permission( creatorsName, createTimestamp, modifiersName, modifyTimestamp, this,
+ appName, permName, description );
+ }
+
+
+ public boolean has( String appName, String permName )
+ throws DataAccessException
+ {
+ String rdn = getRelativeDn( appName, permName );
+
+ try
+ {
+ ctx.getAttributes( rdn );
+ return true;
+ }
+ catch ( NameNotFoundException e )
+ {
+ return false;
+ }
+ catch ( NamingException e )
+ {
+ return false;
+ }
+ }
+
+
+ public Iterator permissionNameIterator( String appName ) throws DataAccessException
+ {
+ String base = getRelativeDn( appName );
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ try
+ {
+ return new JndiIterator( this, PERM_NAME_ID, ctx.search( base,
+ "(& (permName=*) (objectClass=policyPermission) )", controls ), appName );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to search " + base + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ public Iterator permissionIterator( String appName ) throws DataAccessException
+ {
+ String base = getRelativeDn( appName );
+ SearchControls controls = new SearchControls();
+ controls.setReturningAttributes( ATTRIBUTES );
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ try
+ {
+ return new JndiIterator( this, ctx.search( base,
+ "(& (permName=*) (objectClass=policyPermission) )", controls ), appName );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to search " + base + " under " + baseUrl;
+ log.error( msg, e );
+ throw new DataAccessException( msg );
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Private utility methods
+ // -----------------------------------------------------------------------
+
+
+ private String getRelativeDn( String appName, String permName )
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "permName=" ).append( permName );
+ buf.append( ",ou=Permissions,appName=" ).append( appName );
+ buf.append( ",ou=Applications" );
+ return buf.toString();
+ }
+
+
+ private String getRelativeDn( String appName )
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "ou=Permissions,appName=" ).append( appName );
+ buf.append( ",ou=Applications" );
+ return buf.toString();
+ }
+
+
+ // -----------------------------------------------------------------------
+ // LdapDao method implementations
+ // -----------------------------------------------------------------------
+
+
+ public Object getEntryObject( Object extra, Attributes attrs )
+ {
+ String permName = null;
+ String description = null;
+ String creatorsName = null;
+ Date createTimestamp = null;
+ String modifiersName = null;
+ Date modifyTimestamp = null;
+
+ try
+ {
+ permName = ( String ) attrs.get( PERM_NAME_ID ).get();
+ description = LdapUtils.getSingleValued( DESCRIPTION_ID, attrs );
+ creatorsName = LdapUtils.getPrincipal( CREATORS_NAME_ID, attrs );
+ createTimestamp = LdapUtils.getDate( CREATE_TIMESTAMP_ID, attrs );
+ modifiersName = LdapUtils.getPrincipal( MODIFIERS_NAME_ID, attrs );
+ modifyTimestamp = LdapUtils.getDate( MODIFY_TIMESTAMP_ID, attrs );
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed to produce object for attributes: " + attrs;
+ log.error( msg, e );
+ }
+
+ return new Permission( creatorsName, createTimestamp, modifiersName, modifyTimestamp, this,
+ ( String ) extra, permName, description );
+ }
+
+
+ public void deleteEntry( String rdn )
+ {
+ try
+ {
+ ctx.destroySubcontext( rdn );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Failed to delete " + rdn + " under " + baseUrl, e );
+ }
+ }
+}