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 }