| 1 4 package com.nightlabs.ipanema.base.login; 5 6 import java.net.SocketTimeoutException ; 7 import java.rmi.RemoteException ; 8 import java.util.Hashtable ; 9 import java.util.Iterator ; 10 import java.util.LinkedList ; 11 import java.util.List ; 12 import java.util.Properties ; 13 14 import javax.ejb.EJBException ; 15 import javax.naming.CommunicationException ; 16 import javax.naming.InitialContext ; 17 import javax.naming.NamingException ; 18 import javax.security.auth.login.LoginException ; 19 20 import org.apache.commons.beanutils.BeanUtils; 21 import org.apache.commons.lang.exception.ExceptionUtils; 22 import org.apache.log4j.Logger; 23 import org.eclipse.core.runtime.CoreException; 24 import org.eclipse.core.runtime.IConfigurationElement; 25 import org.eclipse.jface.action.IAction; 26 import org.eclipse.swt.widgets.Display; 27 28 import com.nightlabs.config.Config; 29 import com.nightlabs.ipanema.base.IpanemaBasePlugin; 30 import com.nightlabs.ipanema.classloader.IpanemaCLBackend; 31 import com.nightlabs.ipanema.classloader.IpanemaCLBackendUtil; 32 import com.nightlabs.ipanema.classloader.IpanemaCLDelegate; 33 import com.nightlabs.j2ee.InitialContextProvider; 34 import com.nightlabs.rcp.extensionpoint.AbstractEPProcessor; 35 import com.nightlabs.rcp.extensionpoint.EPProcessorException; 36 37 44 public class Login 45 extends AbstractEPProcessor 46 implements InitialContextProvider 47 { 48 public static final Logger LOGGER = Logger.getLogger(Login.class); 49 50 54 public static final int LOGINSTATE_LOGGED_IN = 0; 55 59 public static final int LOGINSTATE_LOGGED_OUT = 1; 60 64 public static final int LOGINSTATE_OFFLINE = 2; 65 66 67 private static Login sharedInstanceLogin = null; 68 69 74 public static class AsyncLoginResult { 75 private Throwable exception = null; 76 private boolean success = false; 77 private String message = ""; 78 private boolean workOffline = false; 79 80 private boolean wasAuthenticationErr = false; 81 private boolean wasCommunicationErr = false; 82 private boolean wasSocketTimeout = false; 83 84 public Throwable getException() { 85 return exception; 86 } 87 public void setException(Throwable exception) { 88 this.exception = exception; 89 } 90 public boolean isSuccess() { 91 return success; 92 } 93 public void setSuccess(boolean success) { 94 this.success = success; 95 } 96 public String getMessage() { 97 return message; 98 } 99 public void setMessage(String message) { 100 this.message = message; 101 } 102 public boolean isWorkOffline() { 103 return workOffline; 104 } 105 public void setWorkOffline(boolean workOffline) { 106 this.workOffline = workOffline; 107 } 108 111 public boolean isWasAuthenticationErr() { 112 return wasAuthenticationErr; 113 } 114 117 public void setWasAuthenticationErr(boolean wasAuthenticationErr) { 118 this.wasAuthenticationErr = wasAuthenticationErr; 119 } 120 123 public boolean isWasCommunicationErr() { 124 return wasCommunicationErr; 125 } 126 129 public void setWasCommunicationErr(boolean wasCommunicationErr) { 130 this.wasCommunicationErr = wasCommunicationErr; 131 } 132 135 public boolean isWasSocketTimeout() { 136 return wasSocketTimeout; 137 } 138 141 public void setWasSocketTimeout(boolean wasSocketTimeout) { 142 this.wasSocketTimeout = wasSocketTimeout; 143 } 144 145 public void copyValuesTo(AsyncLoginResult loginResult) { 146 loginResult.exception = this.exception; 147 loginResult.success = this.success; 148 loginResult.message = this.message; 149 loginResult.workOffline = this.workOffline; 150 151 loginResult.wasAuthenticationErr = this.wasAuthenticationErr; 152 loginResult.wasCommunicationErr = this.wasCommunicationErr; 153 loginResult.wasSocketTimeout = this.wasSocketTimeout; 154 } 155 } 156 157 162 protected static void createLogin(){ 163 sharedInstanceLogin = new Login(); 164 } 165 166 static { 167 createLogin(); 168 } 169 170 174 public boolean isLoggedIn() { 175 return loginContext != null; 176 } 177 178 private static int currLoginState = LOGINSTATE_LOGGED_OUT; 179 184 public static int getLoginState() { 185 return currLoginState; 186 } 187 188 193 public void logout() { 194 IpanemaCLDelegate.sharedInstance().unregister(); 196 loginContext = null; 198 notifyLoginStateListeners(LOGINSTATE_LOGGED_OUT); 199 } 200 201 214 public void doLogin() throws LoginException { 215 doLogin(false); 216 } 217 218 232 public void doLogin(boolean forceLogoutFirst) throws LoginException { 233 if (forceLogoutFirst) 234 logout(); 235 if (loginContext == null) { 236 238 try{ 239 if (sharedInstanceLogin == null) 240 createLogin(); 241 242 final AsyncLoginResult asyncLoginResult = new AsyncLoginResult(); 243 loginContext = new IpanemaLoginContext("ipanema", new LoginCallbackHandler()); 245 246 LOGGER.debug("after syncExec"); 247 248 Display.getDefault().syncExec(new Runnable (){ 250 public void run(){ 251 try { 252 LOGGER.debug("during syncExec"); 253 if (getLoginHandler() != null){ 254 getLoginHandler().handleLogin(loginContext,sharedInstanceLogin.runtimeConfigModule, asyncLoginResult); 255 } else 256 throw new LoginException ("Cannot login, loginHandler is not set!"); 257 } catch(Throwable x) { 258 asyncLoginResult.setException(x); 259 } 260 } 261 }); 262 264 if (asyncLoginResult.getException() != null){ 266 if (asyncLoginResult.getException() instanceof LoginException ) 267 throw (LoginException )asyncLoginResult.getException(); 268 else 269 LOGGER.error("Exception thrown while logging in.",asyncLoginResult.getException()); 270 throw new LoginException (asyncLoginResult.getException().getMessage()); 271 } 272 if (!asyncLoginResult.isSuccess()) { 273 if (asyncLoginResult.isWorkOffline()) { 274 notifyLoginStateListeners(LOGINSTATE_OFFLINE); 276 LoginException lEx = new LoginException (asyncLoginResult.getMessage()); 278 lEx.initCause(new WorkOfflineException(asyncLoginResult.getMessage())); 279 throw lEx; 280 } 281 else 282 throw new LoginException (asyncLoginResult.getMessage()); 283 } 284 285 LOGGER.debug("after syncExec"); 286 287 sharedInstanceLogin.copyPropertiesFrom(loginContext); 289 291 IpanemaCLDelegate.sharedInstance().register(); 294 notifyLoginStateListeners(LOGINSTATE_LOGGED_IN); 296 } catch(Throwable t){ 297 loginContext = null; 298 if (t instanceof LoginException ) 299 throw (LoginException )t; 300 else 301 LOGGER.error("Exception thrown while logging in.",t); 302 throw new LoginException (t.getMessage()); 303 } 304 } 305 } 306 307 313 public static Login getLogin() 314 throws LoginException  315 { 316 return getLogin(true); 317 } 318 319 public static Login sharedInstance() 320 { 321 if (sharedInstanceLogin == null) 322 throw new NullPointerException ("createLogin has not been called! SharedInstance is null!"); 323 return sharedInstanceLogin; 324 } 325 326 333 public static Login getLogin(boolean doLogin) 334 throws LoginException  335 { 336 if (sharedInstanceLogin == null) 337 throw new NullPointerException ("createLogin not called! sharedInstance is null!"); 338 339 if (doLogin) 340 sharedInstanceLogin.doLogin(); 341 return sharedInstanceLogin; 342 } 343 344 private String organisationID; 345 private String userID; 346 private String username; 348 private String password; 349 private String serverURL; 350 private String contextFactory; 351 private String securityProtocol; 352 353 private LoginConfigModule loginConfigModule; 354 private LoginConfigModule runtimeConfigModule = new LoginConfigModule(); 355 356 private IpanemaLoginContext loginContext = null; 358 359 private ILoginHandler loginHandler = null; 361 public ILoginHandler getLoginHandler() { 362 return loginHandler; 363 } 364 368 public void setLoginHandler(ILoginHandler loginHandler) { 369 this.loginHandler = loginHandler; 370 } 371 372 378 protected Login() 379 { 380 if (loginContext != null){ 381 copyPropertiesFrom(loginContext); 382 } 383 384 try { 385 loginConfigModule = ((LoginConfigModule)Config.sharedInstance().createConfigModule(LoginConfigModule.class)); 386 if (loginConfigModule != null) { 387 BeanUtils.copyProperties(runtimeConfigModule,loginConfigModule); 388 } 389 } catch (Exception e) { 390 throw new RuntimeException (e); 391 } 392 } 393 394 395 398 public String getOrganisationID() { 399 return organisationID; 400 } 401 404 public String getUserID() { 405 return userID; 406 } 407 410 public String getPassword() { 411 return password; 412 } 413 414 415 public IpanemaLoginContext getLoginContext() { 416 return loginContext; 417 } 418 419 public void copyPropertiesFrom(IpanemaLoginContext _loginContext){ 420 this.organisationID = _loginContext.getOrganisationID(); 421 this.userID = _loginContext.getUserID(); 422 this.password = _loginContext.getPassword(); 423 this.username = _loginContext.getUsername(); 424 } 425 426 private void copyPropertiesFromConfig(){ 427 this.serverURL = runtimeConfigModule.getServerURL(); 428 this.contextFactory = runtimeConfigModule.getInitialContextFactory(); 429 this.securityProtocol = runtimeConfigModule.getSecurityProtocol(); 430 } 431 432 433 434 protected transient Properties initialContextProperties = null; 435 protected transient InitialContext initialContext = null; 436 437 public void flushInitialContextProperties() { 438 initialContextProperties = null; 439 } 440 441 444 public Hashtable getInitialContextProperties() throws LoginException { 445 447 if (!isLoggedIn()) { 448 LOGGER.debug("getInitialContextProperties(): begin"); 449 doLogin(); 450 451 LOGGER.debug("getInitialContextProperties(): logged in"); 452 453 LOGGER.debug("getInitialContextProperties(): generating props"); 454 } 455 if (initialContextProperties == null){ 456 copyPropertiesFrom(loginContext); 457 copyPropertiesFromConfig(); 458 Properties props = new Properties (); 459 props.put(InitialContext.INITIAL_CONTEXT_FACTORY,contextFactory); 460 props.put(InitialContext.PROVIDER_URL, serverURL); 461 props.put(InitialContext.SECURITY_PRINCIPAL, username); 462 props.put(InitialContext.SECURITY_CREDENTIALS, password); 463 props.put(InitialContext.SECURITY_PROTOCOL, securityProtocol); 464 initialContextProperties = props; 465 } 466 return initialContextProperties; 467 } 468 469 470 471 public InitialContext getInitialContext() throws NamingException , LoginException  472 { 473 LOGGER.debug("getInitialContext(): begin"); 474 doLogin(); 475 LOGGER.debug("getInitialContext(): logged in"); 476 if (initialContext != null) 477 return initialContext; 478 479 LOGGER.debug("getInitialContext(): creating new initctx."); 480 initialContext = new InitialContext (getInitialContextProperties()); 481 return initialContext; 482 } 483 484 490 public LoginConfigModule getLoginConfigModule() { 491 return runtimeConfigModule; 492 } 493 494 495 499 protected static class LoginStateListenerRegistryItem { 500 private LoginStateListener loginStateListener; 501 private IAction action; 502 public LoginStateListenerRegistryItem(LoginStateListener loginStateListener, IAction action) { 503 super(); 504 this.loginStateListener = loginStateListener; 505 this.action = action; 506 } 507 public IAction getAction() { 508 return action; 509 } 510 public LoginStateListener getLoginStateListener() { 511 return loginStateListener; 512 } 513 private boolean checkActionOnEquals = true; 514 515 public boolean isCheckActionOnEquals() { 516 return checkActionOnEquals; 517 } 518 public void setCheckActionOnEquals(boolean checkActionOnEquals) { 519 this.checkActionOnEquals = checkActionOnEquals; 520 } 521 522 public boolean equals(Object o) { 523 if (o instanceof LoginStateListenerRegistryItem) { 524 if ( ((LoginStateListenerRegistryItem)o).getLoginStateListener().equals(this.loginStateListener)) { 525 if (isCheckActionOnEquals()) { 526 return ((LoginStateListenerRegistryItem)o).getAction().equals(this.action); 527 } 528 else 529 return true; 530 } 531 else 532 return false; 533 } 534 else 535 return false; 536 } 537 } 538 539 542 private List loginStateListenerRegistry = new LinkedList (); 543 544 public synchronized void addLoginStateListener(LoginStateListener loginStateListener) { 545 addLoginStateListener(loginStateListener,null); 546 } 547 548 public synchronized void addLoginStateListener(LoginStateListener loginStateListener, IAction action) { 549 LoginStateListenerRegistryItem regItem = new LoginStateListenerRegistryItem(loginStateListener,action); 550 loginStateListenerRegistry.add(regItem); 551 } 552 553 557 public synchronized void removeLoginStateListener(LoginStateListener loginStateListener) { 558 removeLoginStateListener(loginStateListener,null,true); 559 } 560 561 566 public synchronized void removeLoginStateListener(LoginStateListener loginStateListener, boolean allOccurences) { 567 removeLoginStateListener(loginStateListener,null,allOccurences); 568 } 569 570 575 public synchronized void removeLoginStateListener(LoginStateListener loginStateListener, IAction action) { 576 removeLoginStateListener(loginStateListener,action,false); 577 } 578 579 586 public synchronized void removeLoginStateListener(LoginStateListener loginStateListener, IAction action, boolean allOccurencesOfListener) { 587 LoginStateListenerRegistryItem searchItem = new LoginStateListenerRegistryItem(loginStateListener,action); 588 if (allOccurencesOfListener) { 589 searchItem.setCheckActionOnEquals(false); 590 } 591 if (!allOccurencesOfListener) { 592 loginStateListenerRegistry.remove(searchItem); 593 } 594 else { 595 while (loginStateListenerRegistry.contains(searchItem)) { 596 loginStateListenerRegistry.remove(searchItem); 597 } 598 } 599 } 600 601 protected synchronized void notifyLoginStateListeners(int loginState){ 602 if (!isProcessed()) 603 try { 604 process(); 605 } catch (EPProcessorException e) { 606 LOGGER.error("Processing LoginStateListener extensions failed!", e); 607 } 608 609 currLoginState = loginState; 610 for (Iterator it = loginStateListenerRegistry.iterator(); it.hasNext();) { 611 LoginStateListenerRegistryItem item = (LoginStateListenerRegistryItem)it.next(); 612 item.getLoginStateListener().loginStateChanged(loginState,item.getAction()); 613 } 614 } 615 616 623 public void triggerLoginStateNotification() { 624 notifyLoginStateListeners(getLoginState()); 625 } 626 627 630 public String getExtensionPointID() 631 { 632 return "com.nightlabs.ipanema.base.loginstatelistener"; 633 } 634 635 638 public void processElement(IConfigurationElement element) throws EPProcessorException 639 { 640 if ("loginStateListener".equals(element.getName())) { 641 try { 642 LoginStateListener listener = (LoginStateListener) element.createExecutableExtension("class"); 643 addLoginStateListener(listener); 644 } catch (CoreException e) { 645 throw new EPProcessorException(e); 646 } 647 } 648 } 649 650 public static Login.AsyncLoginResult testLogin(IpanemaLoginContext loginContext) { 651 Login.AsyncLoginResult loginResult = new Login.AsyncLoginResult(); 652 653 Login login = null; 654 try { 655 login = Login.getLogin(false); 656 } catch (LoginException e) { 657 LOGGER.error("Obtaining shared instance of Login failed!", e); 658 } 659 660 if ( login != null) 661 login.copyPropertiesFrom(loginContext); 662 else 663 throw new IllegalStateException ("Shared instance of Login must not be null"); 664 665 loginResult.setSuccess(true); 666 loginResult.setMessage(null); 667 loginResult.setException(null); 668 login.flushInitialContextProperties(); 669 670 IpanemaCLBackend ipanemaCLBackend = null; 672 if (ipanemaCLBackend == null) { 674 try { 675 ipanemaCLBackend = IpanemaCLBackendUtil.getHome( 676 login.getInitialContextProperties()).create(); 677 } catch (RemoteException remoteException) { 680 Throwable cause = remoteException.getCause(); 681 if (cause != null && cause.getCause() instanceof EJBException ) { 682 EJBException ejbE = (EJBException )cause.getCause(); 683 if (ejbE != null) { 684 if (ejbE.getCausedByException() instanceof SecurityException ) { 685 loginResult.setWasAuthenticationErr(true); 687 } 688 } 689 } 690 else { 691 if (ExceptionUtils.indexOfThrowable(cause, SecurityException .class) >= 0) 692 loginResult.setWasAuthenticationErr(true); 693 } 694 } catch (LoginException x) { 695 LOGGER.warn("Login failed with a very weird LoginException!", x); 696 IllegalStateException ill = new IllegalStateException ("Caught LoginException although getLogin(FALSE) was executed. "+x.getMessage()); 698 ill.initCause(x); 699 throw ill; 700 } catch (Exception x) { 701 if (x instanceof CommunicationException ) { 702 loginResult.setWasCommunicationErr(true); 703 } 704 if (x instanceof SocketTimeoutException ) { 705 loginResult.setWasSocketTimeout(true); 706 } 707 LOGGER.warn("Login failed!", x); 709 LoginException loginE = new LoginException (x.getMessage()); 710 loginE.initCause(x); 711 loginResult.setSuccess(false); 712 loginResult.setMessage(IpanemaBasePlugin.getResourceString("login.error.unhadledExceptionMessage")); 713 loginResult.setException(loginE); 714 } 715 } 716 return loginResult; 717 } 718 719 } 720 | Popular Tags |