/projects/compiere-330/base/src/org/compiere/model/MLdapProcessor.java
Java | 718 lines | 523 code | 43 blank | 152 comment | 95 complexity | 0869054f336e83c7c58a099012da2590 MD5 | raw file
1/******************************************************************************
2 * Product: Compiere ERP & CRM Smart Business Solution *
3 * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. *
4 * This program is free software, you can redistribute it and/or modify it *
5 * under the terms version 2 of the GNU General Public License as published *
6 * by the Free Software Foundation. This program is distributed in the hope *
7 * that it will be useful, but WITHOUT ANY WARRANTY, without even the implied *
8 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
9 * See the GNU General Public License for more details. *
10 * You should have received a copy of the GNU General Public License along *
11 * with this program, if not, write to the Free Software Foundation, Inc., *
12 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
13 * For the text or an alternative of this public license, you may reach us *
14 * ComPiere, Inc., 3600 Bridge Parkway #102, Redwood City, CA 94065, USA *
15 * or via info@compiere.org or http://www.compiere.org/license.html *
16 *****************************************************************************/
17package org.compiere.model;
18
19import java.sql.*;
20import java.util.*;
21import java.util.logging.*;
22
23import org.compiere.util.*;
24
25
26/**
27 * LDAP Server Model
28 *
29 * @author Jorg Janke
30 * @version $Id$
31 */
32public class MLdapProcessor extends X_AD_LdapProcessor implements CompiereProcessor
33{
34 /**
35 *
36 */
37 private static final long serialVersionUID = 1L;
38
39 /**
40 * Get Active LDAP Server
41 * @return array of Servers
42 */
43 public static MLdapProcessor[] getActive(Ctx ctx)
44 {
45 ArrayList<MLdapProcessor> list = new ArrayList<MLdapProcessor>();
46 String sql = "SELECT * FROM AD_LdapProcessor WHERE IsActive='Y'";
47 PreparedStatement pstmt = null;
48 try
49 {
50 pstmt = DB.prepareStatement(sql, (Trx) null);
51 ResultSet rs = pstmt.executeQuery ();
52 while (rs.next ())
53 list.add (new MLdapProcessor (ctx, rs, null));
54 rs.close ();
55 pstmt.close ();
56 pstmt = null;
57 }
58 catch (Exception e)
59 {
60 s_log.log (Level.SEVERE, sql, e);
61 }
62 try
63 {
64 if (pstmt != null)
65 pstmt.close ();
66 pstmt = null;
67 }
68 catch (Exception e)
69 {
70 pstmt = null;
71 }
72
73 MLdapProcessor[] retValue = new MLdapProcessor[list.size()];
74 list.toArray(retValue);
75 return retValue;
76 } // getActive
77
78 /** Logger */
79 private static CLogger s_log = CLogger.getCLogger (MLdapProcessor.class);
80
81 /**************************************************************************
82 * Ldap Processor
83 * @param ctx context
84 * @param AD_LdapProcessor_ID id
85 * @param trx transaction
86 */
87 public MLdapProcessor(Ctx ctx, int AD_LdapProcessor_ID, Trx trx)
88 {
89 super (ctx, AD_LdapProcessor_ID, trx);
90 } // MLdapProcessor
91
92 /**
93 * Ldap Processor
94 * @param ctx context
95 * @param rs result set
96 * @param trx transaction
97 */
98 public MLdapProcessor(Ctx ctx, ResultSet rs, Trx trx)
99 {
100 super (ctx, rs, trx);
101 } // MLdapProcessor
102
103 /** Array of Clients */
104 private MClient[] m_clients = null;
105 /** Array of Interest Areas */
106 private MInterestArea[] m_interests = null;
107
108 private int m_auth = 0;
109 private int m_ok = 0;
110 private int m_error = 0;
111
112 /**
113 * Get Server ID
114 * @return id
115 */
116 public String getServerID ()
117 {
118 return "Ldap" + get_ID();
119 } // getServerID
120
121 /**
122 * Get Info
123 * @return info
124 */
125 public String getInfo()
126 {
127 return "Auth=" + m_auth
128 + ", OK=" + m_ok + ", Error=" + m_error;
129 } // getInfo
130
131 /**
132 * Get Date Next Run
133 * @param requery requery
134 * @return date next run
135 */
136 public Timestamp getDateNextRun (boolean requery)
137 {
138 if (requery)
139 load(get_Trx());
140 return getDateNextRun();
141 } // getDateNextRun
142
143 /**
144 * Get Logs
145 * @return logs
146 */
147 public CompiereProcessorLog[] getLogs ()
148 {
149 ArrayList<MLdapProcessorLog> list = new ArrayList<MLdapProcessorLog>();
150 String sql = "SELECT * "
151 + "FROM AD_LdapProcessorLog "
152 + "WHERE AD_LdapProcessor_ID=? "
153 + "ORDER BY Created DESC";
154 PreparedStatement pstmt = null;
155 try
156 {
157 pstmt = DB.prepareStatement (sql, get_Trx());
158 pstmt.setInt (1, getAD_LdapProcessor_ID());
159 ResultSet rs = pstmt.executeQuery ();
160 while (rs.next ())
161 list.add (new MLdapProcessorLog (getCtx(), rs, get_Trx()));
162 rs.close ();
163 pstmt.close ();
164 pstmt = null;
165 }
166 catch (Exception e)
167 {
168 log.log(Level.SEVERE, sql, e);
169 }
170 try
171 {
172 if (pstmt != null)
173 pstmt.close ();
174 pstmt = null;
175 }
176 catch (Exception e)
177 {
178 pstmt = null;
179 }
180 MLdapProcessorLog[] retValue = new MLdapProcessorLog[list.size ()];
181 list.toArray (retValue);
182 return retValue;
183 } // getLogs
184
185 /**
186 * Delete old Request Log
187 * @return number of records
188 */
189 public int deleteLog()
190 {
191 if (getKeepLogDays() < 1)
192 return 0;
193 String sql = "DELETE FROM AD_LdapProcessorLog "
194 + "WHERE AD_LdapProcessor_ID=" + getAD_LdapProcessor_ID()
195 //jz + " AND (Created+" + getKeepLogDays() + ") < SysDate";
196 + " AND addDays(Created," + getKeepLogDays() + ") < SysDate";
197 int no = DB.executeUpdate(sql, get_Trx());
198 return no;
199 } // deleteLog
200
201 /**
202 * Get Frequency (n/a)
203 * @return 1
204 */
205 public int getFrequency()
206 {
207 return 1;
208 } // getFrequency
209
210 /**
211 * Get Frequency Type (n/a)
212 * @return minute
213 */
214 public String getFrequencyType()
215 {
216 return X_R_RequestProcessor.FREQUENCYTYPE_Minute;
217 } // getFrequencyType
218
219 /**
220 * Get AD_Schedule_ID
221 * @return 0
222 */
223 public int getAD_Schedule_ID()
224 {
225 return 0;
226 } // getAD_Schedule_ID
227
228 /**
229 * String Representation
230 * @return info
231 */
232 @Override
233 public String toString()
234 {
235 StringBuffer sb = new StringBuffer ("MLdapProcessor[");
236 sb.append (get_ID()).append ("-").append (getName())
237 .append (",Port=").append (getLdapPort())
238 .append ("]");
239 return sb.toString ();
240 } // toString
241
242
243 /**************************************************************************
244 * Authenticate and Authorize
245 * @param ldapUser MLdapUser object
246 * @param usr user name
247 * @param o organization = Client Name
248 * @param ou optional organization unit = Interest Group Value
249 * or Aa<M_Product_ID>aA = Active Asset of Product of user
250 * @param remoteHost remote host name
251 * @param remoteAddr remote host ip address
252 * @return ldapUser MLdapUser with updated information
253 */
254 public MLdapUser authenticate (MLdapUser ldapUser, String usr, String o, String ou,
255 String remoteHost, String remoteAddr)
256 {
257 // Ensure something to return
258 if (ldapUser == null)
259 ldapUser = new MLdapUser();
260
261 String error = null;
262 String info = null;
263
264 // User
265 if (usr == null || usr.trim().length () == 0)
266 {
267 error = "@NotFound@: User (empty)";
268 ldapUser.setErrorString(error);
269 m_error++;
270 log.warning (error);
271 return ldapUser;
272 }
273 usr = usr.trim();
274 // Client
275 if (o == null || o.length () == 0)
276 {
277 error = "@NotFound@: O (Tenant Key missing)";
278 ldapUser.setErrorString(error);
279 m_error++;
280 log.warning (error);
281 return ldapUser;
282 }
283 int AD_Client_ID = findClient(o);
284 if (AD_Client_ID == 0)
285 {
286 error = "@NotFound@: O=" + o + " (Tenant Key)";
287 ldapUser.setErrorString(error);
288 m_error++;
289 log.config (error);
290 return ldapUser;
291 }
292 // Optional Interest Area or Asset
293 int R_InterestArea_ID = 0;
294 int M_Product_ID = 0; // Product of Asset
295 if (ou != null && ou.length () > 0)
296 {
297 if (ou.startsWith("Aa") && ou.endsWith("aA"))
298 {
299 try
300 {
301 String s = ou.substring(2,ou.length()-2);
302 M_Product_ID = Integer.parseInt(s);
303 }
304 catch (Exception e)
305 {
306 }
307 }
308 else
309 R_InterestArea_ID = findInterestArea (AD_Client_ID, ou);
310 if (R_InterestArea_ID == 0 && M_Product_ID == 0)
311 {
312 error = "@NotFound@ OU=" + ou;
313 ldapUser.setErrorString(error);
314 m_error++;
315 log.config (error);
316 return ldapUser;
317 }
318 }
319
320 m_auth++;
321 // Query 1 - Validate User
322 int AD_User_ID = 0;
323 String Value = null;
324 String LdapUser = null;
325 String EMail = null;
326 String Name = null;
327 String Password = null;
328 boolean isActive = false;
329 String EMailVerify = null; // is timestamp
330 boolean isUnique = false;
331 //
332 String sql = "SELECT AD_User_ID, Value, LdapUser, EMail," // 1..4
333 + " Name, Password, IsActive, EMailVerify "
334 + "FROM AD_User "
335 + "WHERE AD_Client_ID=? AND (EMail=? OR Value=? OR LdapUser=?)";
336 PreparedStatement pstmt = null;
337 try
338 {
339 pstmt = DB.prepareStatement(sql, (Trx) null);
340 pstmt.setInt (1, AD_Client_ID);
341 pstmt.setString (2, usr);
342 pstmt.setString (3, usr);
343 pstmt.setString (4, usr);
344 ResultSet rs = pstmt.executeQuery ();
345 if (rs.next())
346 {
347 AD_User_ID = rs.getInt (1);
348 Value = rs.getString (2);
349 LdapUser = rs.getString (3);
350 EMail = rs.getString (4);
351 //
352 Name = rs.getString (5);
353 Password = rs.getString (6);
354 isActive = "Y".equals (rs.getString (7));
355 EMailVerify = rs.getString (8);
356 isUnique = rs.next();
357 }
358 rs.close ();
359 pstmt.close ();
360 pstmt = null;
361 }
362 catch (Exception e)
363 {
364 log.log (Level.SEVERE, sql, e);
365 error = "System Error";
366 }
367 try
368 {
369 if (pstmt != null)
370 pstmt.close ();
371 pstmt = null;
372 }
373 catch (Exception e)
374 {
375 pstmt = null;
376 }
377 if (error != null)
378 {
379 m_error++;
380 ldapUser.setErrorString(error);
381 return ldapUser;
382 }
383 //
384 if (AD_User_ID == 0)
385 {
386 error = "@NotFound@ User=" + usr;
387 info = "User not found - " + usr;
388 }
389 else if (!isActive)
390 {
391 error = "@NotFound@ User=" + usr;
392 info = "User not active - " + usr;
393 }
394 else if (EMailVerify == null)
395 {
396 error = "@UserNotVerified@ User=" + usr;
397 info = "User EMail not verified - " + usr;
398 }
399 else if (usr.equalsIgnoreCase(LdapUser))
400 info = "User verified - Ldap=" + usr
401 + (isUnique ? "" : " - Not Unique");
402 else if (usr.equalsIgnoreCase(Value))
403 info = "User verified - Value=" + usr
404 + (isUnique ? "" : " - Not Unique");
405 else if (usr.equalsIgnoreCase(EMail))
406 info = "User verified - EMail=" + usr
407 + (isUnique ? "" : " - Not Unique");
408 else
409 info = "User verified ?? " + usr
410 + " - Name=" + Name
411 + ", Ldap=" + LdapUser + ", Value=" + Value
412 + (isUnique ? "" : " - Not Unique");
413
414 // Error
415 if (error != null) // should use Language of the User
416 {
417 logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, 0, info, error,
418 remoteHost, remoteAddr);
419 ldapUser.setErrorString(Msg.translate (getCtx(), error));
420 return ldapUser;
421 }
422 // User Info
423 ldapUser.setOrg(o);
424 ldapUser.setOrgUnit(ou);
425 ldapUser.setUserId(usr);
426 ldapUser.setPassword(Password);
427 // Done
428 if (R_InterestArea_ID == 0 && M_Product_ID == 0)
429 {
430 logAccess (AD_Client_ID, AD_User_ID, 0, 0, info, null,
431 remoteHost, remoteAddr);
432 return ldapUser;
433 }
434
435 if (M_Product_ID != 0)
436 return authenticateAsset (ldapUser,
437 AD_User_ID, usr, M_Product_ID,
438 AD_Client_ID, remoteHost, remoteAddr);
439
440 return authenticateSubscription(ldapUser,
441 AD_User_ID, usr, R_InterestArea_ID,
442 AD_Client_ID, remoteHost, remoteAddr);
443 } // authenticate
444
445 /**
446 * Authenticate Subscription
447 * @param ldapUser user
448 * @param AD_User_ID user id
449 * @param usr user authentification (email, ...)
450 * @param R_InterestArea_ID interest area
451 * @param AD_Client_ID client
452 * @param remoteHost remote info
453 * @param remoteAddr remote info
454 * @return user with error message set if error
455 */
456 private MLdapUser authenticateSubscription(MLdapUser ldapUser,
457 int AD_User_ID, String usr, int R_InterestArea_ID,
458 int AD_Client_ID, String remoteHost, String remoteAddr)
459 {
460 String error = null;
461 String info = null;
462
463 // Query 2 - Validate Subscription
464 String OptOutDate = null;
465 boolean found = false;
466 boolean isActive = false;
467 String sql = "SELECT IsActive, OptOutDate "
468 + "FROM R_ContactInterest "
469 + "WHERE R_InterestArea_ID=? AND AD_User_ID=?";
470 PreparedStatement pstmt = null;
471 try
472 {
473 pstmt = DB.prepareStatement(sql, (Trx) null);
474 pstmt.setInt (1, R_InterestArea_ID);
475 pstmt.setInt (2, AD_User_ID);
476 ResultSet rs = pstmt.executeQuery ();
477 if (rs.next())
478 {
479 found = true;
480 isActive = "Y".equals (rs.getString (1));
481 OptOutDate = rs.getString (2);
482 }
483 rs.close ();
484 pstmt.close ();
485 pstmt = null;
486 }
487 catch (Exception e)
488 {
489 log.log (Level.SEVERE, sql, e);
490 error = "System Error (2)";
491 }
492 try
493 {
494 if (pstmt != null)
495 pstmt.close ();
496 pstmt = null;
497 }
498 catch (Exception e)
499 {
500 pstmt = null;
501 }
502 // System Error
503 if (error != null)
504 {
505 m_error++;
506 ldapUser.setErrorString(error);
507 return ldapUser;
508 }
509
510 if (!found)
511 {
512 error = "@UserNotSubscribed@ User=" + usr;
513 info = "No User Interest - " + usr
514 + " - R_InterestArea_ID=" + R_InterestArea_ID;
515 }
516 else if (OptOutDate != null)
517 {
518 error = "@UserNotSubscribed@ User=" + usr + " @OptOutDate@=" + OptOutDate;
519 info = "Opted out - " + usr + " - OptOutDate=" + OptOutDate;
520 }
521 else if (!isActive)
522 {
523 error = "@UserNotSubscribed@ User=" + usr;
524 info = "User Interest Not Active - " + usr;
525 }
526 else
527 info = "User subscribed - " + usr;
528
529
530 if (error != null) // should use Language of the User
531 {
532 logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, 0, info, error,
533 remoteHost, remoteAddr);
534 ldapUser.setErrorString(Msg.translate (getCtx(), error));
535 return ldapUser;
536 }
537 // Done
538 logAccess (AD_Client_ID, AD_User_ID, R_InterestArea_ID, 0, info, null,
539 remoteHost, remoteAddr);
540 return ldapUser;
541 } // authenticateSubscription
542
543 /**
544 * Authenticate Product Asset
545 * @param ldapUser user
546 * @param AD_User_ID user id
547 * @param usr user authentification (email, ...)
548 * @param M_Product_ID product
549 * @param AD_Client_ID client
550 * @param remoteHost remote info
551 * @param remoteAddr remote info
552 * @return user with error message set if error
553 */
554 private MLdapUser authenticateAsset(MLdapUser ldapUser,
555 int AD_User_ID, String usr, int M_Product_ID,
556 int AD_Client_ID, String remoteHost, String remoteAddr)
557 {
558 String error = null;
559 String info = null;
560
561 // Query 2 - Validate Asset
562 MAsset asset = null;
563 String sql = "SELECT * "
564 + "FROM A_Asset "
565 + "WHERE M_Product_ID=?"
566 + " AND AD_User_ID=?"; // only specific user
567 // Will have problems with multiple assets
568 PreparedStatement pstmt = null;
569 try
570 {
571 pstmt = DB.prepareStatement(sql, (Trx) null);
572 pstmt.setInt (1, M_Product_ID);
573 pstmt.setInt (2, AD_User_ID);
574 ResultSet rs = pstmt.executeQuery ();
575 if (rs.next())
576 {
577 asset = new MAsset(getCtx(), rs, null);
578 }
579 rs.close ();
580 pstmt.close ();
581 pstmt = null;
582 }
583 catch (Exception e)
584 {
585 log.log (Level.SEVERE, sql, e);
586 error = "System Error (3)";
587 }
588 try
589 {
590 if (pstmt != null)
591 pstmt.close ();
592 pstmt = null;
593 }
594 catch (Exception e)
595 {
596 pstmt = null;
597 }
598 // System Error
599 if (error != null)
600 {
601 m_error++;
602 ldapUser.setErrorString(error);
603 return ldapUser;
604 }
605 int A_Asset_ID = 0;
606 if (asset == null)
607 {
608 error = "@UserNoAsset@ User=" + usr;
609 info = "No Asset - " + usr + " - " + M_Product_ID;
610 }
611 else if (!asset.isActive())
612 {
613 A_Asset_ID = asset.getA_Asset_ID();
614 error = "@UserNoAsset@ User=" + usr;
615 info = "Asset not active - " + usr;
616 }
617 else if (!asset.isActive(true))
618 {
619 A_Asset_ID = asset.getA_Asset_ID();
620 error = "@UserNoAsset@ User=" + usr + " @GuaranteeDate@=" + asset.getGuaranteeDate();
621 info = "Expired - " + usr + " - GuaranteeDate=" + asset.getGuaranteeDate();
622 }
623 else
624 info = "Asset - " + usr;
625
626
627 if (error != null) // should use Language of the User
628 {
629 logAccess (AD_Client_ID, AD_User_ID, 0, A_Asset_ID, info, error,
630 remoteHost, remoteAddr);
631 ldapUser.setErrorString(Msg.translate (getCtx(), error));
632 return ldapUser;
633 }
634 // Done OK
635 MLdapAccess log = logAccess (AD_Client_ID, AD_User_ID, 0, asset.getA_Asset_ID(), info, null,
636 remoteHost, remoteAddr);
637 MAssetDelivery ad = new MAssetDelivery(asset, null, log.toString(), AD_User_ID);
638 ad.setRemote_Host(remoteHost);
639 ad.setRemote_Addr(remoteAddr);
640 ad.save();
641 return ldapUser;
642 } // authenticateAsset
643
644
645 /**
646 * Find Client
647 * @param client client name
648 * @return AD_Client_ID
649 */
650 private int findClient (String client)
651 {
652 if (m_clients == null)
653 m_clients = MClient.getAll(getCtx());
654 for (MClient element : m_clients) {
655 if ((client.equalsIgnoreCase (element.getValue())))
656 return element.getAD_Client_ID ();
657 }
658 return 0;
659 } // findClient
660
661 /**
662 * Find Interest Area
663 * @param interset Name client name
664 * @return AD_Client_ID
665 */
666 private int findInterestArea (int AD_Client_ID, String interestArea)
667 {
668 if (m_interests == null)
669 m_interests = MInterestArea.getAll(getCtx());
670 for (MInterestArea element : m_interests) {
671 if (AD_Client_ID == element.getAD_Client_ID()
672 && interestArea.equalsIgnoreCase (element.getValue ()))
673 return element.getR_InterestArea_ID();
674 }
675 return 0;
676 } // findInterestArea
677
678 /**
679 * Log Access
680 * @param AD_Client_ID client
681 * @param AD_User_ID user
682 * @param R_InterestArea_ID interest area
683 * @param info info
684 * @param error error
685 */
686 private MLdapAccess logAccess (int AD_Client_ID,
687 int AD_User_ID, int R_InterestArea_ID, int A_Asset_ID,
688 String info, String error,
689 String remoteHost, String remoteAddr)
690 {
691 if (error != null)
692 {
693 log.log (Level.CONFIG, info);
694 m_error++;
695 }
696 else
697 {
698 log.log (Level.INFO, info);
699 m_ok++;
700 }
701 //
702 MLdapAccess access = new MLdapAccess (getCtx(), 0, null);
703 access.setAD_Client_ID (AD_Client_ID);
704 access.setAD_Org_ID(0);
705 access.setAD_LdapProcessor_ID(getAD_LdapProcessor_ID());
706 access.setAD_User_ID (AD_User_ID);
707 access.setR_InterestArea_ID (R_InterestArea_ID);
708 access.setA_Asset_ID(A_Asset_ID);
709 access.setRemote_Host(remoteHost);
710 access.setRemote_Addr(remoteAddr);
711
712 access.setIsError (error != null);
713 access.setSummary (info);
714 access.save();
715 return access;
716 } // logAccess
717
718} // MLdapProcessor