Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

additional changes to non-senate user activation, including email aut…

…h and registration
  • Loading branch information...
commit 482d00881f1bb50881d3e3e660f0bd1056417d89 1 parent 723f49a
authored January 18, 2011
1  .gitignore
@@ -3,3 +3,4 @@ target/
3 3
 src/main/webapp/WEB-INF/lib/
4 4
 src/main/webapp/WEB-INF/config.xml
5 5
 src/main/webapp/img/avatars
  6
+*.properties
7  pom.xml
@@ -24,7 +24,12 @@
24 24
 			<groupId>org.jasypt</groupId>
25 25
 			<artifactId>jasypt</artifactId>
26 26
 			<version>1.7</version>
27  
-			<classifier>lite</classifier>
  27
+			<scope>compile</scope>
  28
+		</dependency>
  29
+		<dependency>
  30
+			<groupId>javax.mail</groupId>
  31
+			<artifactId>mail</artifactId>
  32
+			<version>1.4.1</version>
28 33
 			<scope>compile</scope>
29 34
 		</dependency>
30 35
 		<dependency>
13  src/main/java/gov/nysenate/opendirectory/models/ExternalPerson.java
... ...
@@ -1,11 +1,15 @@
1 1
 package gov.nysenate.opendirectory.models;
2 2
 
3 3
 import java.util.Arrays;
  4
+import java.util.Date;
4 5
 import java.util.TreeSet;
5 6
 
  7
+import org.jasypt.util.text.BasicTextEncryptor;
  8
+
6 9
 import gov.nysenate.opendirectory.models.interfaces.IPerson;
7 10
 import gov.nysenate.opendirectory.utils.BCrypt;
8 11
 
  12
+
9 13
 public class ExternalPerson implements IPerson {
10 14
 	
11 15
 	private String firstName;
@@ -83,8 +87,13 @@ public void setAuthorizationHash(String authorizationHash) {
83 87
 		this.authorizationHash = authorizationHash;
84 88
 	}
85 89
 	
86  
-	
87  
-	
  90
+	public void setAuthorizationHash() {
  91
+		BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
  92
+		String dateTime = Long.toString(new Date().getTime());
  93
+		textEncryptor.setPassword(dateTime + email);
  94
+		this.authorizationHash = textEncryptor.encrypt(
  95
+				dateTime + email).replaceAll("=|&|\\?|\\+|/|\\p{Cntrl}","");
  96
+	}
88 97
 	public boolean checkPassword(String password) {
89 98
 		return BCrypt.checkpw(password, hash);
90 99
 	}
172  src/main/java/gov/nysenate/opendirectory/servlets/NonSenateAccessServlet.java
@@ -2,11 +2,10 @@
2 2
 
3 3
 import gov.nysenate.opendirectory.ldap.Ldap;
4 4
 import gov.nysenate.opendirectory.models.ExternalPerson;
5  
-import gov.nysenate.opendirectory.servlets.UserServlet.UserServletException;
  5
+import gov.nysenate.opendirectory.utils.Mailer;
6 6
 import gov.nysenate.opendirectory.utils.Request;
7 7
 
8 8
 import java.io.IOException;
9  
-import java.io.PrintWriter;
10 9
 
11 10
 import javax.naming.NamingException;
12 11
 import javax.servlet.ServletException;
@@ -48,9 +47,14 @@ else if(command.equals("logout")) {
48 47
 			else if(command.equals("register")) {
49 48
 				self.render("external/register.jsp");
50 49
 			}
  50
+			else if(command.equals("auth")) {
  51
+				doExternalAuth(self);
  52
+			}
51 53
 	    	else throw new ExternalServletException("Invalid command `"+command+"` supplied.");
52 54
 		} catch (ExternalServletException e) {
53 55
 			doException(self,e);
  56
+		} catch (SolrServerException e) {
  57
+			e.printStackTrace();
54 58
 		}
55 59
 	}
56 60
 
@@ -69,7 +73,7 @@ else if(command.equals("register")) {
69 73
 	    		doExternalRegister(self);
70 74
 	    	}
71 75
 	    	else if(command.equals("auth")) {
72  
-	    		doExternalAuth(self);
  76
+	    		self.httpResponse.getWriter().println("hey");//doExternalAuth(self);
73 77
 	    	}
74 78
 	    	else throw new ExternalServletException("Invalid command `"+command+"` supplied.");
75 79
 		} catch (ExternalServletException e) {
@@ -111,39 +115,39 @@ private void doExternalRegister(Request self) throws IOException, ServletExcepti
111 115
 				error += "<br/>Entered matching passwords";
112 116
 			}
113 117
 		}
114  
-		if(email1 == null || email1.equals("") || !email1.matches(".+?@(.*+\\.state\\.ny\\.us|ny\\.gov)")) {
115  
-			error += "<br/>Entered a valid email address (ending in state.ny.us or ny.gov)";
116  
-		}
117  
-		else {
118  
-			if(email2 == null || !email1.equals(email2)) {
119  
-				
120  
-			}
121  
-			else {
122  
-				ExternalPerson person = self.solrSession.loadExternalPersonByEmail(email1);
123  
-				if(person != null) {
124  
-					if(person.getAuthorized()) {
125  
-						error = "<br/>That email address already exists on OpenDirectory.  If you need help " +
126  
-								"retrieving your password please " +
127  
-								"<a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
128  
-					}
129  
-					else {
130  
-						error = "<br/>That email address already exists on OpenDirectory, so we've dispatched " +
131  
-								"another activation email.  If you do not receive the email or have any questions " +
132  
-								"please <a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
133  
-						//TODO: resend activation email
134  
-					}
135  
-				}
136  
-			}
137  
-		}
  118
+//		if(email1 == null || email1.equals("") || !email1.matches(".+?@(.*+\\.state\\.ny\\.us|ny\\.gov)")) {
  119
+//			error += "<br/>Entered a valid email address (ending in state.ny.us or ny.gov)";
  120
+//		}
  121
+//		else {
  122
+//			if(email2 == null || !email1.equals(email2)) {
  123
+//				
  124
+//			}
  125
+//			else {
  126
+//				ExternalPerson person = self.solrSession.loadExternalPersonByEmail(email1);
  127
+//				if(person != null) {
  128
+//					if(person.getAuthorized()) {
  129
+//						error = "<br/>That email address already exists on OpenDirectory.  If you need help " +
  130
+//								"retrieving your password please " +
  131
+//								"<a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
  132
+//					}
  133
+//					else {
  134
+//						error = "<br/>That email address already exists on OpenDirectory, so we've dispatched " +
  135
+//								"another activation email.  If you do not receive the email or have any questions " +
  136
+//								"please <a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
  137
+//						Mailer.sendExternalAuthorizationMail(person);
  138
+//					}
  139
+//				}
  140
+//			}
  141
+//		}
138 142
 		
139 143
 		
140 144
 		if(error.equals("")) {
141 145
 			ExternalPerson person = new ExternalPerson(firstName, lastName, email1, phone);
142  
-			person.setAuthorized(true);
  146
+			person.setAuthorized(false);
143 147
 			person.encryptPassword(password1);
144  
-			//TODO: set authorized false
145  
-			//TODO: make auth
146  
-			//TODO: send activation email
  148
+			person.setAuthorizationHash();
  149
+			
  150
+			Mailer.sendExternalAuthorizationMail(person);
147 151
 			
148 152
 			self.solrSession.saveExternalPerson(person);
149 153
 			
@@ -166,29 +170,117 @@ private void doExternalRegister(Request self) throws IOException, ServletExcepti
166 170
 		
167 171
 	}
168 172
 
169  
-	private void doExternalAuth(Request self) {
  173
+	private void doExternalAuth(Request self) throws SolrServerException, IOException, ServletException {
  174
+		String email = ((String)self.httpRequest.getParameter("email"));
  175
+		String key = (String)self.httpRequest.getParameter("key");
  176
+		
  177
+		if(email == null || key == null) {
  178
+			populateMessage(self, MessageCode.CREDS_NOT_PROVIDED);
  179
+		}
170 180
 		
  181
+		ExternalPerson person = self.solrSession.loadExternalPersonByEmail(email);
  182
+		
  183
+		if(person == null) {
  184
+			//couldn't find person
  185
+			populateMessage(self, MessageCode.PERSON_NOT_FOUND);
  186
+		}
  187
+		else {
  188
+			if(person.getAuthorized()) {
  189
+				//no need
  190
+				populateMessage(self, MessageCode.ALREADY_AUTHORIZED);
  191
+			}
  192
+			else {
  193
+				if(person.getAuthorizationHash().equals(key)) {
  194
+					person.setAuthorizationHash("");
  195
+					person.setAuthorized(true);
  196
+					self.solrSession.saveExternalPerson(person);
  197
+					populateMessage(self, MessageCode.AUTH_SUCCESS);
  198
+				}
  199
+				else {
  200
+					//bad hash
  201
+					person.setAuthorizationHash();
  202
+					Mailer.sendExternalAuthorizationMail(person);
  203
+					populateMessage(self, MessageCode.AUTH_FAILURE);
  204
+				}
  205
+			}
  206
+		}
  207
+		self.render("external/message.jsp");
  208
+	}
  209
+	
  210
+	public enum MessageCode {
  211
+		CREDS_NOT_PROVIDED, PERSON_NOT_FOUND, ALREADY_AUTHORIZED, AUTH_SUCCESS, AUTH_FAILURE, NOT_ACTIVATED
  212
+	}
  213
+	
  214
+	public void populateMessage(Request self, MessageCode code) {
  215
+		String header = null;
  216
+		String error = null;
  217
+		String message = null;
  218
+		switch(code) {
  219
+			case CREDS_NOT_PROVIDED:
  220
+				header = "Error";
  221
+				error = "<br/>Invalid credentials specified, if you think this is an error" +
  222
+					"please <a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
  223
+				break;
  224
+			case PERSON_NOT_FOUND:
  225
+				header = "Error";
  226
+				error = "<br/>We could not find this person.  Are you sure you've " +
  227
+						"<a href=\"" + urls.url("external","register") + "\">registered</a>?" + 
  228
+						"  If you think this is an error please " +
  229
+						"<a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
  230
+				break;
  231
+			case ALREADY_AUTHORIZED:
  232
+				header = "Error";
  233
+				error = "<br/>This person is already authorized, if you think this is an error" +
  234
+					"please <a href=\"http://www.nysenate.gov/contact\">contact us</a>." +
  235
+					"  Or click <a href=\"" + urls.url("external","login") + "\">here</a> to login.";
  236
+				break;
  237
+			case AUTH_SUCCESS:
  238
+				header = "Success";
  239
+				message = "<br/>Your account has been activated.  You can click " +
  240
+					"<a href=\"" + urls.url("external","login") + "\">here</a> to login.";
  241
+				break;
  242
+			case AUTH_FAILURE:
  243
+				header = "Error";
  244
+				error = "<br/>There was an error authorizing your account, so we've dispatched " +
  245
+					"another activation email.  If you do not receive the email or have any questions " +
  246
+					"please <a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
  247
+				break;
  248
+			case NOT_ACTIVATED:
  249
+				header = "Error";
  250
+				error = "<br/>Your account must be activated before you can log in.  You should have " + 
  251
+					"received an email when you first reigstered which containts an activation link, " + 
  252
+					"if not we've dispatched another activation email.  If you do not receive the email " +
  253
+					"or have any questions please <a href=\"http://www.nysenate.gov/contact\">contact us</a>.";
  254
+				break;
  255
+		}
  256
+		self.httpRequest.setAttribute("header", header);
  257
+		self.httpRequest.setAttribute("error", error);
  258
+		self.httpRequest.setAttribute("message", message);
171 259
 	}
172 260
 
173 261
 	private void doExternalLogin(Request self) throws IOException, ServletException {
174  
-
175  
-		String cred = ((String)self.httpRequest.getParameter("name")).toLowerCase();
  262
+		String cred = ((String)self.httpRequest.getParameter("name"));
176 263
 		String pass = (String)self.httpRequest.getParameter("password");
177 264
 		ExternalPerson person = self.solrSession.loadExternalPersonByEmail(cred);
178 265
 		
179 266
 		//check login correct
180 267
 		if(person != null && pass != null && person.checkPassword(pass)) {
181  
-			self.httpSession.setAttribute("externalPerson", person.getFirstName());
182  
-			self.httpSession.setAttribute("externalUid", person.getEmail());
183  
-			self.redirect(urls.url("index"));
  268
+			if(person.getAuthorized()) {
  269
+				self.httpSession.setAttribute("externalPerson", person.getFirstName());
  270
+				self.httpSession.setAttribute("externalUid", person.getEmail());
  271
+				self.redirect(urls.url("index"));
  272
+			}
  273
+			else {
  274
+				populateMessage(self, MessageCode.NOT_ACTIVATED);
  275
+				Mailer.sendExternalAuthorizationMail(person);
  276
+				self.render("external/message.jsp");
  277
+			}
  278
+			
184 279
 		}
185 280
 		else {
186 281
 			self.httpRequest.setAttribute("errorMessage", "Username and/or password were incorrect.  Are you sure you've <a href=\"" + urls.url("external","register") + "\">registered?</a>");
187 282
 			self.render("external/login.jsp");
188 283
 		}
189  
-
190  
-		
191  
-		
192 284
 	}
193 285
 
194 286
 	public void doException(Request self, ExternalServletException e) throws ServletException, IOException {
2  src/main/java/gov/nysenate/opendirectory/solr/SolrSession.java
@@ -36,7 +36,7 @@ public static void main(String[] args) throws SolrServerException, IOException {
36 36
 		
37 37
 		Solr solr = new Solr().connect();
38 38
 		SolrSession session = solr.newSession(Person.getAdmin());
39  
-		
  39
+		session.deleteByUid("williams@ny.gov");
40 40
 	}
41 41
 	
42 42
 	public SolrSession(IPerson user, Solr solr) {
86  src/main/java/gov/nysenate/opendirectory/utils/Mailer.java
... ...
@@ -0,0 +1,86 @@
  1
+package gov.nysenate.opendirectory.utils;
  2
+
  3
+import gov.nysenate.opendirectory.models.ExternalPerson;
  4
+
  5
+import java.util.Date;
  6
+import java.util.Properties;
  7
+import java.util.StringTokenizer;
  8
+
  9
+import javax.mail.Message;
  10
+import javax.mail.PasswordAuthentication;
  11
+import javax.mail.Session;
  12
+import javax.mail.Transport;
  13
+import javax.mail.internet.InternetAddress;
  14
+import javax.mail.internet.MimeMessage;
  15
+
  16
+public class Mailer {
  17
+	private static final String SMTP_HOST_NAME = Resource.get("hostname");
  18
+
  19
+	private static final String SMTP_PORT = Resource.get("port");
  20
+	
  21
+	private static final String SMTP_ACCOUNT_USER = Resource.get("user");
  22
+	private static final String SMTP_ACCOUNT_PASS = Resource.get("pass");
  23
+	
  24
+	public static void sendMail(String to, String subject, String message, String from, String fromDisplay) throws Exception {
  25
+		Properties props = new Properties();
  26
+		props.put("mail.smtp.host", SMTP_HOST_NAME);
  27
+		props.put("mail.smtp.auth", "true");
  28
+		props.put("mail.debug", "true");
  29
+		props.put("mail.smtp.port", SMTP_PORT);
  30
+		props.put("mail.smtp.starttls.enable","false");
  31
+		props.put("mail.smtp.socketFactory.port", SMTP_PORT);
  32
+		props.put("mail.smtp.socketFactory.fallback", "false");
  33
+		props.put("mail.smtp.ssl.enable","false");
  34
+
  35
+		Session session = Session.getDefaultInstance(props,	new javax.mail.Authenticator() {
  36
+										protected PasswordAuthentication getPasswordAuthentication() {
  37
+											return new PasswordAuthentication(SMTP_ACCOUNT_USER, SMTP_ACCOUNT_PASS);}});
  38
+		session.setDebug(false);
  39
+		Message msg = new MimeMessage(session);
  40
+		InternetAddress addressFrom = new InternetAddress(from);
  41
+		addressFrom.setPersonal(fromDisplay);
  42
+		msg.setFrom(addressFrom);
  43
+	
  44
+		
  45
+		StringTokenizer st = new StringTokenizer (to,",");
  46
+		
  47
+		InternetAddress[] rcps = new InternetAddress[st.countTokens()];
  48
+		int idx = 0;
  49
+		
  50
+		while (st.hasMoreTokens())
  51
+		{
  52
+			InternetAddress addressTo = new InternetAddress(st.nextToken());
  53
+			rcps[idx++] = addressTo;
  54
+			
  55
+		}
  56
+		
  57
+		msg.setRecipients(Message.RecipientType.TO,rcps);
  58
+		
  59
+		msg.setSubject(subject);
  60
+		msg.setContent(message, "text/html");
  61
+		Transport.send(msg);
  62
+	}
  63
+
  64
+	public static void sendExternalAuthorizationMail(ExternalPerson person) {
  65
+		String authUrl = "http://directory.nysenate.gov/external/auth?email=" + person.getEmail() +
  66
+		"&key=" + person.getAuthorizationHash();
  67
+		
  68
+		String to = person.getEmail();
  69
+		String subject = "Authorize your NYSS OpenDirectory account";
  70
+		String message = "Hello " + person.getFirstName() + ", <br/><br/>" + 
  71
+			"It appears that you signed up to view the NYSS OpenDirectory, " +
  72
+			"in order to finalize this subscription you must click <a href\"" + authUrl + "\">here<a/> or open the following url: <br/><br/>" +
  73
+			authUrl + "<br/><br/>" + 
  74
+			"If you have any questions please <a href=\"http://www.nysenate.gov/contact\">contact us</a>.<br/><br/>";
  75
+		
  76
+		String from = "OpenDirectory@nysenate.gov";
  77
+		String fromDisplay = "NYSS OpenDirectory";
  78
+		
  79
+		try {
  80
+			sendMail(to, subject, message, from, fromDisplay);
  81
+		} catch (Exception e) {
  82
+			e.printStackTrace();
  83
+		}
  84
+	}
  85
+	
  86
+}
2  src/main/java/gov/nysenate/opendirectory/utils/Request.java
@@ -61,6 +61,8 @@ public Request(BaseServlet servlet, HttpServletRequest request,HttpServletRespon
61 61
 		if(httpSession.getAttribute("frontPagePeople") == null) {
62 62
 			httpSession.setAttribute("frontPagePeople", new FrontPagePeople(this));
63 63
 		}
  64
+		
  65
+		Resource.init(this.servlet);
64 66
 	}
65 67
 	
66 68
 	public void render(String name) throws IOException, ServletException {
63  src/main/java/gov/nysenate/opendirectory/utils/Resource.java
... ...
@@ -0,0 +1,63 @@
  1
+package gov.nysenate.opendirectory.utils;
  2
+
  3
+import java.io.File;
  4
+import java.io.FileInputStream;
  5
+import java.io.FileNotFoundException;
  6
+import java.io.InputStream;
  7
+import java.util.Properties;
  8
+import javax.servlet.ServletContext;
  9
+import javax.servlet.http.HttpServlet;
  10
+
  11
+/**
  12
+ * @author Jared Williams
  13
+ *	This class is the property loader and accessor.  It allows the properties file
  14
+ *	to be accessed from both the servlet and non-servlet context
  15
+ */
  16
+public class Resource {
  17
+	
  18
+	private static String servletResource = "/WEB-INF/app.properties";
  19
+	private static String classResource = "app.properties";
  20
+	private static InputStream INPUT;
  21
+	private static Properties properties;
  22
+	private static ServletContext CONTEXT;
  23
+	
  24
+	/*
  25
+	 * If current context is servlet grab resource stream and load props, otherwise
  26
+	 * use typical file reader
  27
+	 * 
  28
+	 */
  29
+	private static Properties load() {
  30
+		try{
  31
+			if(properties == null) {
  32
+				properties = new Properties();
  33
+				if(CONTEXT == null) {
  34
+					init();
  35
+				}
  36
+				else {
  37
+					INPUT = CONTEXT.getResourceAsStream(servletResource);
  38
+				}
  39
+				properties.load(INPUT);
  40
+			}
  41
+		}
  42
+		catch (Exception e) {
  43
+			e.printStackTrace();
  44
+			properties = null;
  45
+		}
  46
+		return properties;
  47
+	}
  48
+	
  49
+	public static void init() throws FileNotFoundException {
  50
+		INPUT = new FileInputStream(new File(classResource));
  51
+	}
  52
+	
  53
+	/*
  54
+	 * Would be called from the servlet, saves Servlet 
  55
+	 */
  56
+	public static void init(HttpServlet hs) {
  57
+		CONTEXT = hs.getServletContext();
  58
+	}
  59
+	
  60
+	public static String get(String key) {
  61
+		return load().getProperty(key);
  62
+	}
  63
+}
3  src/main/webapp/jsp/external/message.jsp
@@ -4,6 +4,9 @@
4 4
 	String message = (String)request.getAttribute("message");
5 5
 	String header = (String)request.getAttribute("header");
6 6
 	
  7
+	if(header ==  null && message == null && error == null) {
  8
+		response.sendRedirect(urls.url("index"));
  9
+	}
7 10
 
8 11
 %>
9 12
 <jsp:include page="header.jsp" />

0 notes on commit 482d008

Please sign in to comment.
Something went wrong with that request. Please try again.