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 }