john pfeiffer
  • Home
  • Categories
  • Tags
  • Archives

AppProperties AuthgatewayService

// 2012-08-29 johnpfeiffer requires JohnStringUtils, validation-api, bval-core, bval-jsr303, commons-beanutils-core, commons-lang3

import java.util.ArrayList;
import java.util.Set;

import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

class AuthgatewayService
{
    protected static final String PARAMACTIVE = "active";
    protected static final String PARAMHOST = "ldapServerHost";
    protected static final String PARAMPORT = "ldapServerPort";
    protected static final String PARAMSSL = "ldapSSL";
    protected static final String PARAMBASEDN = "ldapBaseDn";
    protected static final String PARAMUSERDN = "ldapManagerUserDn";
    protected static final String PARAMUSERDNPASSWORD = "ldapManagerPassword";
    protected static final String PARAMSEARCHBASE = "ldapUserSearchBase";
    protected static final String PARAMLDAPUSERATTRIBUTE = "ldapUserAttribute";

    protected static final String PARAMSEARCHFILTER = "ldapUserSearchFilter";
    protected static final String PARAMSEARCHSUBTREE = "ldapSearchSubtree";
    protected static final String PARAMSEARCHGROUPS = "ldapSearchGroups";
    protected static final String PARAMSEARCHGROUPSBASE = "ldapGroupSearchBase";
    protected static final String PARAMSEARCHGROUPSUSERATTRIBUTE = "ldapGroupRoleAttributeName";
    protected static final String PARAMSEARCHGROUPSMEMBERATTRIBUTE = "ldapGroupMemberAttributeName";

    private boolean active = true;

    @NotNull( message = "ERROR: hostname cannot be null" )
    private String ldapServerHost;

    @Min( value = 0 , message = "ERROR: port number too small, must be between 0 and 65535" )
    @Max( value = 65535 , message = "ERROR: port number too large, must be between 0 and 65535" )
    private int port = 389;

    private boolean ldapSSL = false;

    @NotNull( message = "ERROR: baseDN cannot be null" )
    private LdapName ldapBaseDn;

    @NotNull( message = "ERROR: binding user DN cannot be null" )
    private LdapName ldapManagerUserDn;

    @NotNull( message = "ERROR: binding user password cannot be null" )
    private String ldapManagerPassword;

    @NotNull( message = "ERROR: user attribute cannot be null" )
    private String ldapUserAttribute = "sAMAccountName"; // ldap uses uid

    @NotNull( message = "ERROR: User search filter cannot be null" )
    private String ldapUserSearchFilter = "";

    @NotNull( message = "ERROR: User search base cannot be null" )
    private LdapName ldapUserSearchBase;

    private boolean ldapSearchSubtree = true;

    private boolean ldapSearchGroups = false;

    @NotNull( message = "ERROR: Groups search base cannot be null" )
    private LdapName ldapGroupSearchBase;

    @NotNull( message = "ERROR: Group search attribute cannot be null" )
    private String ldapGroupRoleAttributeName;

    @NotNull( message = "ERROR: Group search member attribute cannot be null" )
    private String ldapGroupMemberAttributeName;

    public static class Builder
    {
        private boolean active = true;
        private String ldapServerHost;
        private int port = 389;
        private boolean ldapSSL = false;
        private LdapName ldapBaseDn;
        private LdapName ldapManagerUserDn;
        private String ldapManagerPassword;
        private String ldapUserAttribute;
        private String ldapUserSearchFilter = "";
        private LdapName ldapUserSearchBase;
        private boolean ldapSearchSubtree = true;
        private boolean ldapSearchGroups = false;
        private LdapName ldapGroupSearchBase;
        private String ldapGroupRoleAttributeName;
        private String ldapGroupMemberAttributeName;

        Builder()
        {
            try
            {
                ldapGroupSearchBase = new LdapName( "cn=Users" );
            }catch( InvalidNameException e )
            {
                throw new IllegalArgumentException( "ERROR: default constructor search base is invalid " + e.getMessage() );
            }
            ldapGroupRoleAttributeName = "cn";
            ldapGroupMemberAttributeName = "member";
        }

        public Builder active( boolean value )
        {
            this.active = value;
            return this;
        }

        public Builder hostname( String value )
        {
            this.ldapServerHost = value;
            return this;
        }

        public Builder port( int value )
        {
            this.port = value;
            return this;
        }

        public Builder ldapSSL( boolean value )
        {
            this.ldapSSL = value;
            return this;
        }

        public Builder ldapBaseDn( LdapName value )
        {
            this.ldapBaseDn = value;
            return this;
        }

        public Builder ldapManagerUserDn( LdapName value )
        {
            this.ldapManagerUserDn = value;
            return this;
        }

        public Builder ldapManagerPassword( String value )
        {
            this.ldapManagerPassword = value;
            return this;
        }

        public Builder ldapUserAttribute( String value )
        {
            this.ldapUserAttribute = value;
            return this;
        }

        public Builder ldapUserSearchFilter( String value )
        {
            this.ldapUserSearchFilter = value;
            return this;
        }

        public Builder ldapUserSearchBase( LdapName value )
        {
            this.ldapUserSearchBase = value;
            return this;
        }

        public Builder ldapSearchSubtree( boolean value )
        {
            this.ldapSearchSubtree = value;
            return this;
        }

        public Builder ldapSearchGroups( boolean value )
        {
            this.ldapSearchGroups = value;
            return this;
        }

        public Builder ldapGroupSearchBase( LdapName value )
        {
            this.ldapGroupSearchBase = value;
            return this;
        }

        public Builder ldapGroupRoleAttributeName( String value )
        {
            this.ldapGroupRoleAttributeName = value;
            return this;
        }

        public Builder ldapGroupMemberAttributeName( String value )
        {
            this.ldapGroupMemberAttributeName = value;
            return this;
        }

        public AuthgatewayService build() throws IllegalArgumentException
        {
            AuthgatewayService authgateway = new AuthgatewayService( this ); // object may exist in an incomplete or illegal state
            AuthgatewayServiceValidator( authgateway );
            return authgateway;
        }

        private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

        private void AuthgatewayServiceValidator( AuthgatewayService authgateway ) throws IllegalArgumentException
        {
            Set <ConstraintViolation <AuthgatewayService>> violations = validator.validate( authgateway );
            if( !violations.isEmpty() )
            {
                for( ConstraintViolation <?> v : violations )
                {
                    throw new IllegalArgumentException( v.getMessage() );
                }
            }
            // ConstraintViolations ensure all of the values are non null

            if( this.active ) // only apply constraints to an active service
            {
                if( this.ldapServerHost.isEmpty() )
                {
                    throw new IllegalArgumentException( "ERROR: hostname cannot be empty" );
                }
                if( JohnStringUtils.containsWhiteSpace( ldapServerHost ) )
                {
                    throw new IllegalArgumentException( "ERROR: hostname cannot contain whitespace" );
                }
                if( this.ldapManagerPassword.isEmpty() )
                {
                    throw new IllegalArgumentException( "ERROR: password cannot be empty" );
                }
                if( JohnStringUtils.containsWhiteSpace( ldapManagerPassword ) )
                {
                    throw new IllegalArgumentException( "ERROR: password cannot contain whitespace" );
                }
                if( !this.ldapUserAttribute.equalsIgnoreCase( "uid" ) && !this.ldapUserAttribute.toLowerCase().equalsIgnoreCase( "samaccountname" ) )
                {
                    throw new IllegalArgumentException( "ERROR: userAttribute is unsupported: " + this.ldapUserAttribute );
                }
            }
        }

    } // end inner class Builder

    private AuthgatewayService( Builder builder ) throws IllegalArgumentException
    {
        this.active = builder.active;
        this.ldapServerHost = builder.ldapServerHost;
        this.port = builder.port;
        this.ldapSSL = builder.ldapSSL;
        this.ldapBaseDn = builder.ldapBaseDn;
        this.ldapManagerUserDn = builder.ldapManagerUserDn;
        this.ldapManagerPassword = builder.ldapManagerPassword;
        this.ldapUserAttribute = builder.ldapUserAttribute;
        this.ldapUserSearchFilter = builder.ldapUserSearchFilter;
        this.ldapUserSearchBase = builder.ldapUserSearchBase;
        this.ldapSearchSubtree = builder.ldapSearchSubtree;
        this.ldapSearchGroups = builder.ldapSearchGroups;
        this.ldapGroupSearchBase = builder.ldapGroupSearchBase;
        this.ldapGroupRoleAttributeName = builder.ldapGroupRoleAttributeName;
        this.ldapGroupMemberAttributeName = builder.ldapGroupMemberAttributeName;
    }

    protected boolean isActive()
    {
        return active;
    }

    protected String TestConnection() throws IllegalArgumentException
    {
        LdapSearch ldaptest = new LdapSearch.Builder().hostname( ldapServerHost ).port( port ).baseDN( ldapBaseDn ).bindUserDN( ldapManagerUserDn )
                .password( ldapManagerPassword ).userAttribute( ldapUserAttribute ).searchBase( ldapUserSearchBase ).build();
        ArrayList <String> queryResults = ldaptest.queryForBindingUser();
        return queryResults.toString();
    }

    // primary use is for saving to persistence (file)
    protected String getString( String header )
    {
        String newline = System.getProperty( "line.separator" );
        StringBuilder strb = new StringBuilder();
        strb.append( header + PARAMACTIVE + "=" + active + newline );
        strb.append( header + PARAMHOST + "=" + ldapServerHost + newline );
        strb.append( header + PARAMPORT + "=" + port + newline );
        strb.append( header + PARAMSSL + "=" + ldapSSL + newline );
        strb.append( header + PARAMBASEDN + "=" + ldapBaseDn + newline );
        strb.append( header + PARAMUSERDN + "=" + ldapManagerUserDn + newline );
        strb.append( header + PARAMUSERDNPASSWORD + "=" + ldapManagerPassword + newline );
        strb.append( header + PARAMSEARCHBASE + "=" + ldapUserSearchBase + newline );
        strb.append( header + PARAMLDAPUSERATTRIBUTE + "=" + ldapUserAttribute + newline );
        strb.append( header + PARAMSEARCHFILTER + "=" + ldapUserSearchFilter + newline );
        strb.append( header + PARAMSEARCHSUBTREE + "=" + ldapSearchSubtree + newline );
        strb.append( header + PARAMSEARCHGROUPS + "=" + ldapSearchGroups + newline );
        strb.append( header + PARAMSEARCHGROUPSBASE + "=" + ldapGroupSearchBase + newline );
        strb.append( header + PARAMSEARCHGROUPSUSERATTRIBUTE + "=" + ldapGroupRoleAttributeName + newline );
        strb.append( header + PARAMSEARCHGROUPSMEMBERATTRIBUTE + "=" + ldapGroupMemberAttributeName + newline );
        return strb.toString();
    }

    protected String getHTMLForm()
    {
        StringBuilder strb = new StringBuilder();
        String newline = "<br /><br />" + System.getProperty( "line.separator" );
        String space = "&#xA0;";

        strb.append( "<label>AD/LDAP Server Address: </label>" + space + space + " <input type='text' name='" + PARAMHOST + "' size='40' value='"
                + JohnStringUtils.safeHTML( ldapServerHost ) + "' /> " + newline );

        strb.append( "<label>AD/LDAP Port: </label> " );
        strb.append( "<input type='radio' name='" + PARAMPORT + "' value='389' " );
        if( port == 389 )
        {
            strb.append( "checked='checked'" );
        }
        strb.append( " /> <label>389</label>" );
        strb.append( "<input type='radio' name='" + PARAMPORT + "' value='636' " );
        if( port == 636 )
        {
            strb.append( "checked='checked'" );
        }
        strb.append( " /> <label> 636 </label> " + newline );
        // SSL true false is handled in Controller depending if port is 389 or 636

        strb.append( "<label>AD/LDAP Base DN: </label>" + space + space + "<input type='text' id='" + PARAMBASEDN + "' name='" + PARAMBASEDN
                + "' size='40' value='" + JohnStringUtils.safeHTML( ldapBaseDn.toString() ) + "' /> " + newline );
        strb.append( "<label>AD/LDAP Binding User DN: </label>" + space + space + "<input type='text' id='" + PARAMUSERDN + "' name='" + PARAMUSERDN
                + "' size='80' value='" + JohnStringUtils.safeHTML( ldapManagerUserDn.toString() ) + "' /> " + newline );
        strb.append( "<label>AD/LDAP Binding User password: </label>" + space + space + "<input type='password' id='" + PARAMUSERDNPASSWORD + "' name='"
                + PARAMUSERDNPASSWORD + "' size='40' /> " + newline );
        strb.append( "<label>AD/LDAP Search Base (if left empty it will use the BaseDN): </label>" + space + space + "<input type='text' id='" + PARAMSEARCHBASE
                + "' name='" + PARAMSEARCHBASE + "' size='80' value='" + JohnStringUtils.safeHTML( ldapUserSearchBase.toString() ) + "' /> " + newline );
        strb.append( "<label>Search Attribute (AD = sAMAccountName , LDAP = uid) </label> " );
        strb.append( "<input type='radio' name='" + PARAMLDAPUSERATTRIBUTE + "' value='sAMAccountName' " );
        if( "sAMAccountName".equals( ldapUserAttribute ) )
        {
            strb.append( "checked='checked'" );
        }
        strb.append( " /> <label>sAMAccountName</label>" );
        strb.append( "<input type='radio' name='" + PARAMLDAPUSERATTRIBUTE + "' value='uid' " );
        if( "uid".equals( ldapUserAttribute ) )
        {
            strb.append( "checked='checked'" );
        }
        strb.append( " /> <label> uid </label> " + newline );

        strb.append( "<label>AD/LDAP Search Subtree: </label><input name='" + PARAMSEARCHSUBTREE + "' type='checkbox' " );
        if( ldapSearchSubtree )
        {
            strb.append( " checked='checked' " );
        }
        strb.append( " /> " + newline );
        return strb.toString();
    }

    // TODO: more generic validation from the Data Model
    protected static String getValidateFormOnSubmit()
    {
        StringBuilder strb = new StringBuilder();
        String newline = System.getProperty( "line.separator" );
        String javascriptBackslash = "\\\\";
        strb.append( newline + "<script type='text/javascript'>" + newline );
        strb.append( "function validateFormOnSubmit()  {" + newline );

        strb.append( "var userDN=document.getElementById( '" + PARAMUSERDN + "' ).value;" + newline );
        strb.append( "if( userDN==null || userDN=='' )" + newline );
        strb.append( "{ alert('Error: userDN cannot be blank');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "if( userDN.indexOf( '" + javascriptBackslash + "' ) != -1 )" + newline );
        strb.append( "{ alert('Error: userDN should not include back slashes');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "var baseDN=document.getElementById( '" + PARAMBASEDN + "' ).value;" + newline );
        strb.append( "if( baseDN==null || baseDN=='' )" + newline );
        strb.append( "{ alert('Error: baseDN cannot be blank');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "if( baseDN.indexOf( '" + javascriptBackslash + "' ) != -1 )" + newline );
        strb.append( "{ alert('Error: BaseDN should not include back slashes');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "var searchBase=document.getElementById( '" + PARAMSEARCHBASE + "' ).value;" + newline );
        strb.append( "var baseDNUpperCase=baseDN.toUpperCase();" );
        strb.append( "var searchBaseUpperCase=searchBase.toUpperCase();" );
        strb.append( "if( searchBaseUpperCase.indexOf( baseDNUpperCase ) != -1 )" + newline );
        strb.append( "{ alert('Error: Search Base does not need to contain the BaseDN');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "if( searchBase.indexOf( '" + javascriptBackslash + "' ) != -1 )" + newline );
        strb.append( "{ alert('Error: searchBase should not include back slashes');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "var password=document.getElementById( '" + PARAMUSERDNPASSWORD + "' ).value;" + newline );
        strb.append( "if( password==null || password=='' )" + newline );
        strb.append( "{ alert('Error: password cannot be blank');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "if( password.indexOf( '" + javascriptBackslash + "' ) != -1 )" + newline );
        strb.append( "{ alert('Error: password should not include back slashes');" + newline );
        strb.append( " return false; }" + newline );

        strb.append( "}" + newline );

        strb.append( "</script>" + newline );
        return strb.toString();
    }

} // end class

  • « AppProperties AtmosService
  • AppProperties AuthgatewayServiceDAO »

Published

Aug 30, 2012

Category

java-servlet

~1238 words

Tags

  • appproperties 18
  • authgatewayservice 1
  • java-servlet 61