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