View Javadoc
1   package org.argeo.cms.ui.util;
2   
3   import java.util.Locale;
4   
5   import javax.security.auth.Subject;
6   import javax.security.auth.login.LoginContext;
7   import javax.security.auth.login.LoginException;
8   import javax.servlet.http.HttpServletRequest;
9   
10  import org.apache.commons.logging.Log;
11  import org.apache.commons.logging.LogFactory;
12  import org.argeo.api.NodeConstants;
13  import org.argeo.cms.CmsException;
14  import org.argeo.cms.auth.CurrentUser;
15  import org.argeo.cms.ui.CmsImageManager;
16  import org.argeo.cms.ui.CmsView;
17  import org.argeo.cms.ui.UxContext;
18  import org.argeo.cms.ui.widgets.auth.CmsLogin;
19  import org.argeo.cms.ui.widgets.auth.CmsLoginShell;
20  import org.argeo.eclipse.ui.specific.UiContext;
21  import org.eclipse.rap.rwt.RWT;
22  import org.eclipse.rap.rwt.application.EntryPoint;
23  import org.eclipse.swt.events.SelectionListener;
24  import org.eclipse.swt.widgets.Composite;
25  import org.eclipse.swt.widgets.Display;
26  
27  public class LoginEntryPoint implements EntryPoint, CmsView {
28  	protected final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
29  	protected final static String HEADER_AUTHORIZATION = "Authorization";
30  	private final static Log log = LogFactory.getLog(LoginEntryPoint.class);
31  	private LoginContext loginContext;
32  	private UxContext uxContext = null;
33  
34  	@Override
35  	public int createUI() {
36  		final Display display = createDisplay();
37  		UiContext.setData(CmsView.KEY, this);
38  		CmsLoginShell loginShell = createCmsLoginShell();
39  		try {
40  			// try pre-auth
41  			loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, loginShell);
42  			loginContext.login();
43  		} catch (LoginException e) {
44  			loginShell.createUi();
45  			loginShell.open();
46  
47  			// HttpServletRequest request = RWT.getRequest();
48  			// String authorization = request.getHeader(HEADER_AUTHORIZATION);
49  			// if (authorization == null ||
50  			// !authorization.startsWith("Negotiate")) {
51  			// HttpServletResponse response = RWT.getResponse();
52  			// response.setStatus(401);
53  			// response.setHeader(HEADER_WWW_AUTHENTICATE, "Negotiate");
54  			// response.setDateHeader("Date", System.currentTimeMillis());
55  			// response.setDateHeader("Expires", System.currentTimeMillis() +
56  			// (24 * 60 * 60 * 1000));
57  			// response.setHeader("Accept-Ranges", "bytes");
58  			// response.setHeader("Connection", "Keep-Alive");
59  			// response.setHeader("Keep-Alive", "timeout=5, max=97");
60  			// // response.setContentType("text/html; charset=UTF-8");
61  			// }
62  
63  			while (!loginShell.getShell().isDisposed()) {
64  				if (!display.readAndDispatch())
65  					display.sleep();
66  			}
67  		}
68  
69  		if (CurrentUser.getUsername(getSubject()) == null)
70  			return -1;
71  		uxContext = new SimpleUxContext();
72  		return postLogin();
73  	}
74  
75  	protected Display createDisplay() {
76  		return new Display();
77  	}
78  
79  	protected int postLogin() {
80  		return 0;
81  	}
82  
83  	protected HttpServletRequest getRequest() {
84  		return RWT.getRequest();
85  	}
86  
87  	protected CmsLoginShell createCmsLoginShell() {
88  		return new CmsLoginShell(this) {
89  
90  			@Override
91  			public void createContents(Composite parent) {
92  				LoginEntryPoint.this.createLoginPage(parent, this);
93  			}
94  
95  			@Override
96  			protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
97  					SelectionListener loginSelectionListener) {
98  				LoginEntryPoint.this.extendsCredentialsBlock(credentialsBlock, selectedLocale, loginSelectionListener);
99  			}
100 
101 		};
102 	}
103 
104 	/**
105 	 * To be overridden. CmsLogin#createCredentialsBlock() should be called at
106 	 * some point in order to create the credentials composite. In order to use
107 	 * the default layout, call CmsLogin#defaultCreateContents() but <b>not</b>
108 	 * CmsLogin#createContent(), since it would lead to a stack overflow.
109 	 */
110 	protected void createLoginPage(Composite parent, CmsLogin login) {
111 		login.defaultCreateContents(parent);
112 	}
113 
114 	protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
115 			SelectionListener loginSelectionListener) {
116 
117 	}
118 
119 	@Override
120 	public void navigateTo(String state) {
121 		// TODO Auto-generated method stub
122 
123 	}
124 
125 	@Override
126 	public void authChange(LoginContext loginContext) {
127 		if (loginContext == null)
128 			throw new CmsException("Login context cannot be null");
129 		// logout previous login context
130 		if (this.loginContext != null)
131 			try {
132 				this.loginContext.logout();
133 			} catch (LoginException e1) {
134 				log.warn("Could not log out: " + e1);
135 			}
136 		this.loginContext = loginContext;
137 	}
138 
139 	@Override
140 	public void logout() {
141 		if (loginContext == null)
142 			throw new CmsException("Login context should not bet null");
143 		try {
144 			CurrentUser.logoutCmsSession(loginContext.getSubject());
145 			loginContext.logout();
146 		} catch (LoginException e) {
147 			throw new CmsException("Cannot log out", e);
148 		}
149 	}
150 
151 	@Override
152 	public void exception(Throwable e) {
153 		// TODO Auto-generated method stub
154 
155 	}
156 
157 	// @Override
158 	// public LoginContext getLoginContext() {
159 	// return loginContext;
160 	// }
161 
162 	protected Subject getSubject() {
163 		return loginContext.getSubject();
164 	}
165 
166 	@Override
167 	public boolean isAnonymous() {
168 		return CurrentUser.isAnonymous(getSubject());
169 	}
170 
171 	@Override
172 	public CmsImageManager getImageManager() {
173 		// TODO Auto-generated method stub
174 		return null;
175 	}
176 
177 	@Override
178 	public UxContext getUxContext() {
179 		return uxContext;
180 	}
181 }