001    package railo.runtime.tag;
002    
003    import java.io.IOException;
004    
005    import javax.naming.NamingException;
006    import javax.naming.directory.DirContext;
007    import javax.naming.directory.SearchControls;
008    
009    import railo.commons.lang.ClassException;
010    import railo.runtime.exp.ApplicationException;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.ext.tag.TagImpl;
013    import railo.runtime.net.ldap.LDAPClient;
014    import railo.runtime.op.Caster;
015    import railo.runtime.tag.util.DeprecatedUtil;
016    import railo.runtime.type.List;
017    import railo.runtime.type.Query;
018    import railo.runtime.type.util.ArrayUtil;
019    
020    // TODO tag ldap 
021    // attr rebind
022    
023    /**
024    * Provides an interface to LDAP Lightweight Directory Access Protocol 
025    * directory servers like the Netscape Directory Server.
026    */
027    public final class Ldap extends TagImpl {
028    
029        private String delimiter=";";    
030        private String server;
031        private int port=389;
032        private short secureLevel=LDAPClient.SECURE_NONE;
033        private String[] returnAsBinary=new String[0];
034        private String attributes=null;
035        private String username;
036        private String password;
037        private String action="query";
038        private String[] sort=new String[0];
039        private String dn;
040        private int referral; 
041        private int scope=SearchControls.SUBTREE_SCOPE;
042        
043        private int sortType=LDAPClient.SORT_TYPE_CASE;
044        private int sortDirection=LDAPClient.SORT_DIRECTION_ASC;
045        
046        private int startrow=1;
047        private int timeout=60000;
048        private int maxrows;
049        private String name; 
050        private String start;
051        private String separator=",";
052        private String filter="objectclass = *";
053        private int modifyType=DirContext.REPLACE_ATTRIBUTE;
054        private boolean rebind;
055    
056    
057        /**
058         * @see railo.runtime.ext.tag.TagImpl#release()
059         */
060        public void release() {
061            action="query";
062            delimiter=";";
063            port=389;
064            secureLevel=LDAPClient.SECURE_NONE;
065            returnAsBinary=new String[0];
066            username=null;
067            password=null;
068            referral=0;
069            attributes=null;
070            sort=new String[0];
071            dn=null;
072            name=null;
073            scope=SearchControls.SUBTREE_SCOPE;
074            
075            startrow=1;
076            timeout=60000;
077            maxrows=-1; 
078            
079            sortType=LDAPClient.SORT_TYPE_CASE;
080            sortDirection=LDAPClient.SORT_DIRECTION_ASC;
081            
082            start=null;
083            separator=",";
084            filter="objectclass = *";
085            modifyType=DirContext.REPLACE_ATTRIBUTE;
086            rebind=false;
087            
088            super.release();
089            
090        }
091    
092    
093        /**
094         * @param filterfile The filterfile to set.
095         * @throws ApplicationException 
096         */
097        public void setFilterfile(String filterfile) {
098                    DeprecatedUtil.tagAttribute(pageContext,"LDAP", "filterfile");
099        }
100        
101        /** Specifies the character that cfldap uses to separate multiple 
102         * attribute name/value pairs when more than one attribute is specified 
103         * in the attribute attribute or the attribute that you want to use has 
104         * the default delimiter character, which is the semicolon (;), 
105         * such as mgrpmsgrejecttext;lang-en. The delimiter character is used by the query, 
106         * add, and modify action attributes, and is used by cfldap to output multi-value attributes
107         * @param delimiter delimeter to set
108         */ 
109        public void setDelimiter(String delimiter) {
110            this.delimiter = delimiter;
111        }
112        
113        /**
114         * Used in conjunction with action = "Query". Specifies the first row of the LDAP query to insert 
115         * into the query. The default is 1.
116         * @param startrow The startrow to set.
117         */
118        public void setStartrow(double startrow) {
119            this.startrow = (int)startrow;
120        }
121    
122        /**
123         * Specifies the maximum number of entries for LDAP queries.
124         * @param maxrows The maxrows to set.
125         */
126        public void setMaxrows(double maxrows) {
127            this.maxrows = (int)maxrows;
128        }
129    
130        /**
131         * Specifies the maximum amount of time, in seconds, to wait for LDAP processing. Defaults to 
132         * 60 seconds.
133         * @param timeout The timeout to set.
134         */
135        public void setTimeout(double timeout) {
136            this.timeout = (int)timeout;
137        }
138        
139        /**
140         * @param password The password to set.
141         */
142        public void setPassword(String password) {
143            this.password = password;
144        }
145    
146    
147        /**
148         * Port defaults to the standard LDAP port, 389.
149         * @param port The port to set.
150         */
151        public void setPort(double port) {
152            this.port = (int) port;
153        }
154    
155    
156        /**
157         * Identifies the type of security to employ, CFSSL_BASIC or CFSSL_CLIENT_AUTH, 
158         * and additional information that is required by the specified security type.
159         * @param referral The referral to set.
160         */
161        public void setReferral(double referral) {
162            this.referral = (int) referral;
163        }
164    
165    
166        /**
167         * Host name "biff.upperlip.com" or IP address "192.1.2.225" of the LDAP server.
168         * @param server The server to set.
169         */
170        public void setServer(String server) {
171            this.server = server;
172        }
173    
174    
175        /**
176         * If no user name is specified, the LDAP connection is anonymous.
177         * @param username The username to set.
178         */
179        public void setUsername(String username) {
180            this.username = username;
181        }
182    
183    
184        /**
185         * @param secure The secureLevel to set.
186         * @throws ApplicationException 
187         */
188        public void setSecure(String secure) throws ApplicationException {
189            secure=secure.trim().toUpperCase();
190            if(secure.equals("CFSSL_BASIC")) secureLevel=LDAPClient.SECURE_CFSSL_BASIC;
191            else if(secure.equals("CFSSL_CLIENT_AUTH")) secureLevel=LDAPClient.SECURE_CFSSL_CLIENT_AUTH;
192            else throw new ApplicationException("invalid value for attribute secure ["+secure+"], valid values are [CFSSL_BASIC, CFSSL_CLIENT_AUTH]");
193        }
194        /**
195         * Specifies the scope of the search from the entry specified in the Start attribute 
196         * for action = "Query".
197         * @param strScope The scope to set.
198         * @throws ApplicationException 
199         */
200        public void setScope(String strScope) throws ApplicationException {
201            strScope=strScope.trim().toLowerCase();
202            if(strScope.equals("onelevel")) scope=SearchControls.ONELEVEL_SCOPE;
203            else if(strScope.equals("base")) scope=SearchControls.OBJECT_SCOPE;
204            else if(strScope.equals("subtree")) scope=SearchControls.SUBTREE_SCOPE;
205            else throw new ApplicationException("invalid value for attribute scope ["+strScope+"], valid values are [oneLevel,base,subtree]");
206        }
207        
208        /**
209         * Indicates whether to add, delete, or replace an attribute 
210         * in a multi-value list of attributes.
211         * @param modifyType The modifyType to set.
212         * @throws ApplicationException 
213         */ 
214        public void setModifytype(String modifyType) throws ApplicationException {
215            modifyType=modifyType.trim().toLowerCase();
216            if(modifyType.equals("add")) this.modifyType=DirContext.ADD_ATTRIBUTE;
217            else if(modifyType.equals("delete")) this.modifyType=DirContext.REMOVE_ATTRIBUTE;
218            else if(modifyType.equals("replace")) this.modifyType=DirContext.REPLACE_ATTRIBUTE;
219            else throw new ApplicationException("invalid value for attribute modifyType ["+modifyType+"], valid values are [add,replace,delete]");
220        }
221        
222        /**
223         * @param returnAsBinary The returnAsBinary to set.
224         * @throws PageException 
225         */
226        public void setReturnasbinary(String returnAsBinary) throws PageException {
227            this.returnAsBinary = ArrayUtil.trim(List.toStringArray(List.listToArrayRemoveEmpty(returnAsBinary,',')));
228        }
229        
230        /**
231         * Indicates the attribute or attributes by which to sort query results. 
232         * Use a comma [,] to separate attributes.
233         * @param sort The sort to set.
234         * @throws PageException 
235         */
236        public void setSort(String sort) throws PageException {
237            this.sort = ArrayUtil.trim(List.toStringArray(List.listToArrayRemoveEmpty(sort,','))); 
238        }
239        
240        /**
241         * Specifies how to sort query results.
242         * @param sortControl sortControl to set
243         * @throws PageException 
244         */
245        public void setSortcontrol(String sortControl) throws PageException {
246            String[] sortControlArr = ArrayUtil.trim(List.toStringArray(List.listToArrayRemoveEmpty(sortControl,','))); 
247            for(int i=0;i<sortControlArr.length;i++) {
248                String scs=sortControlArr[i].trim().toLowerCase();
249                
250                if(scs.equals("asc"))sortDirection=LDAPClient.SORT_DIRECTION_ASC;
251                else if(scs.equals("desc")) sortDirection=LDAPClient.SORT_DIRECTION_DESC;
252                else if(scs.equals("case"))sortType=LDAPClient.SORT_TYPE_CASE;
253                else if(scs.equals("nocase"))sortType=LDAPClient.SORT_TYPE_NOCASE;
254                else throw new ApplicationException("invalid value for attribute sortControl ["+sortControl+"], " +
255                        "valid values are [asc,desc,case,nocase]");
256            }
257        }
258        
259        /**
260         * @param strAttributes
261         */
262        public void setAttributes(String strAttributes) {
263            attributes = strAttributes;
264        }
265        
266        /**
267         * Specifies the LDAP action.
268         * @param action The action to set.
269         */
270        public void setAction(String action) {
271            this.action=action.trim().toLowerCase();
272        }
273    
274    
275        /**
276         * Specifies the distinguished name for update actions.
277         * @param dn The dn to set.
278         */
279        public void setDn(String dn) {
280            this.dn = dn;
281        }
282    
283    
284        /**
285         * The name you assign to the LDAP query.
286         * @param name The name to set.
287         */
288        public void setName(String name) {
289            this.name = name;
290        }
291    
292    
293        /**
294         * Specifies the character that cfldap uses to separate attribute values in multi-value attributes. 
295         * This character is used by the query, add, and modify action attributes, and 
296         * by cfldap to output multi-value attributes. The default character is the comma (,).
297         * @param separator The separator to set.
298         */
299        public void setSeparator(String separator) {
300            this.separator = separator;
301        }
302    
303    
304        /**
305         * Specifies the distinguished name of the entry to be used to start the search.
306         * @param start The start to set.
307         */
308        public void setStart(String start) {
309            this.start = start;
310        }
311    
312    
313        /**
314         * @param filter The filter to set.
315         */
316        public void setFilter(String filter) {
317            this.filter = filter;
318        }
319    
320        /**
321         * If you set rebind to Yes, cfldap attempts to rebind the referral callback and reissue the query 
322         * by the referred address using the original credentials. The default is No, which means referred 
323         * connections are anonymous.
324         * @param rebind The rebind to set.
325         */
326        public void setRebind(boolean rebind) {
327            this.rebind = rebind;
328        }
329        
330    
331        
332        
333        /**
334         * @see railo.runtime.ext.tag.TagImpl#doStartTag()
335         */
336        public int doStartTag() throws PageException {
337            try {
338                return _doStartTag();
339            } 
340            catch (Exception e) {
341                throw Caster.toPageException(e);
342            }
343        }
344        private int _doStartTag() throws NamingException, PageException, IOException, ClassException {
345            
346            //LDAPClient client=new LDAPClient(server,port,secureLevel,returnAsBinary,username,password,referral);
347            LDAPClient client=new LDAPClient(server,port,returnAsBinary);
348            if(secureLevel!=LDAPClient.SECURE_NONE)client.setSecureLevel(secureLevel);
349            if(username!=null)client.setCredential(username,password);
350            if(referral>0) client.setReferral(referral);
351            
352            if(action.equals("add")) {
353                required("LDAP",action,"attributes",attributes);
354                required("LDAP",action,"dn",dn);
355                client.add(dn,attributes,delimiter,separator);
356            }
357            else if(action.equals("delete")) {
358                required("LDAP",action,"dn",dn);
359                client.delete(dn);
360            }
361            else if(action.equals("modifydn")) {
362                required("LDAP",action,"attributes",attributes);
363                required("LDAP",action,"dn",dn);
364                client.modifydn(dn,attributes);
365            }
366            else if(action.equals("modify")) {
367                required("LDAP",action,"attributes",attributes);
368                required("LDAP",action,"dn",dn);
369                client.modify(dn,modifyType,attributes,delimiter,separator);
370            }
371            else if(action.equals("query")) {
372                required("LDAP",action,"start",start);
373                required("LDAP",action,"attributes",attributes);
374                required("LDAP",action,"name",name);
375                Query qry = client.query(attributes,scope,startrow,maxrows,
376                        timeout,sort,sortType,sortDirection,start,separator,filter);
377                pageContext.setVariable(name,qry);
378                
379            } 
380            else throw new ApplicationException("invalid value for attribute action ["+action+"], valid values are [add,delete,modifydn,modify,query]");
381            
382            return SKIP_BODY;
383        }
384    
385    
386    
387    
388    }