2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.vaadin
.view
;
11 import java
.util
.List
;
13 import org
.apache
.commons
.lang
.StringUtils
;
14 import org
.apache
.log4j
.Logger
;
15 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
16 import org
.springframework
.security
.authentication
.AuthenticationManager
;
17 import org
.springframework
.security
.authentication
.UsernamePasswordAuthenticationToken
;
18 import org
.springframework
.security
.core
.Authentication
;
19 import org
.springframework
.security
.core
.AuthenticationException
;
20 import org
.vaadin
.spring
.events
.Event
;
21 import org
.vaadin
.spring
.events
.EventBus
;
22 import org
.vaadin
.spring
.events
.EventBus
.ViewEventBus
;
23 import org
.vaadin
.spring
.events
.EventBusListener
;
25 import com
.vaadin
.spring
.annotation
.SpringComponent
;
26 import com
.vaadin
.spring
.annotation
.ViewScope
;
28 import eu
.etaxonomy
.cdm
.vaadin
.event
.AuthenticationAttemptEvent
;
29 import eu
.etaxonomy
.cdm
.vaadin
.event
.AuthenticationSuccessEvent
;
30 import eu
.etaxonomy
.vaadin
.mvp
.AbstractPresenter
;
31 import eu
.etaxonomy
.vaadin
.ui
.navigation
.NavigationEvent
;
32 import eu
.etaxonomy
.vaadin
.ui
.navigation
.NavigationManager
;
35 * The {@link LoginView} is used as replacement view in the scope of other views.
36 * Therefore the LoginPresenter must be in <b>UIScope</b> so that the LoginPresenter
37 * is available to all Views.
39 * The LoginPresenter offers a <b>auto login feature for developers</b>. To activate the auto login
40 * you need to provide the <code>user name</code> and <code>password</code> using the environment variables
41 * <code>cdm-vaadin.login.usr</code> and <code>cdm-vaadin.login.pwd</code>, e.g.:
43 * -Dcdm-vaadin.login.usr=admin -Dcdm-vaadin.login.pwd=00000
46 * @author a.kohlbecker
52 public class LoginPresenter
extends AbstractPresenter
<LoginView
> implements EventBusListener
<AuthenticationAttemptEvent
> {
54 private static final long serialVersionUID
= 4020699735656994791L;
56 private static final Logger log
= Logger
.getLogger(LoginPresenter
.class);
58 private final static String PROPNAME_USER
= "cdm-vaadin.login.usr";
60 private final static String PROPNAME_PASSWORD
= "cdm-vaadin.login.pwd";
62 private String redirectToState
;
64 protected EventBus
.UIEventBus uiEventBus
;
70 protected void eventViewBusSubscription(ViewEventBus viewEventBus
) {
71 // not listening to view scope events
75 protected void setUIEventBus(EventBus
.UIEventBus uiEventBus
){
76 this.uiEventBus
= uiEventBus
;
77 uiEventBus
.subscribe(this);
80 public boolean authenticate(String userName
, String password
) {
82 getView().clearMessage();
84 UsernamePasswordAuthenticationToken token
= new UsernamePasswordAuthenticationToken(userName
, password
);
85 AuthenticationManager authenticationManager
= getRepo().getAuthenticationManager();
87 Authentication authentication
= authenticationManager
.authenticate(token
);
88 if(authentication
!= null && authentication
.isAuthenticated()) {
89 log
.debug("user '" + userName
+ "' authenticated");
90 currentSecurityContext().setAuthentication(authentication
);
91 if(NavigationManager
.class.isAssignableFrom(getNavigationManager().getClass())){
92 uiEventBus
.publish(this, new AuthenticationSuccessEvent(userName
));
93 log
.debug("redirecting to " + redirectToState
);
94 uiEventBus
.publish(this, new NavigationEvent(redirectToState
));
97 } catch (AuthenticationException e
){
98 getView().showErrorMessage("Login failed! Please check your username and password.");
109 public void handleViewEntered() {
111 List
<String
> redirectToStateTokens
= getNavigationManager().getCurrentViewParameters();
112 String currentViewName
= getNavigationManager().getCurrentViewName();
114 if(currentViewName
.equals(LoginViewBean
.NAME
) && redirectToStateTokens
.isEmpty()){
115 // login view is shown in turn to an explicit login request of the user (e.g. login button pressed)
116 // use the redirectToStateTokens 1-n as redirectToState
117 //FIXME implement : redirectToState = UserView.NAME
120 // the login view is shown instead of the requested view for which the user needs to login
121 redirectToState
= String
.join("/", redirectToStateTokens
);
124 // attempt to auto login
125 if(StringUtils
.isNotEmpty(System
.getProperty(PROPNAME_USER
)) && StringUtils
.isNotEmpty(System
.getProperty(PROPNAME_PASSWORD
))){
126 log
.warn("Performing autologin with user " + System
.getProperty(PROPNAME_USER
));
127 authenticate(System
.getProperty(PROPNAME_USER
), System
.getProperty(PROPNAME_PASSWORD
));
132 public void onEvent(Event
<AuthenticationAttemptEvent
> event
) {
133 if(getView()!= null){
134 authenticate(event
.getPayload().getUserName(), getView().getLoginDialog().getPassword().getValue());
136 log
.info("view is NULL, not yet disposed LoginPresenter?");