Add LDAP authentication and enabling Spring logging
[proteocache.git] / server / compbio / controllers / UserController.java
1 package compbio.controllers;
2
3 import java.util.Date;
4 import java.util.regex.Pattern;
5
6 import javax.naming.directory.DirContext;
7
8 import org.springframework.ldap.core.LdapTemplate;
9 import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.dao.DataIntegrityViolationException;
12 import org.springframework.mail.SimpleMailMessage;
13 import org.springframework.security.ldap.LdapUtils;
14 import org.springframework.ldap.core.ContextSource;
15 import org.springframework.stereotype.Controller;
16 import org.springframework.ui.Model;
17 import org.springframework.ui.ModelMap;
18 import org.springframework.validation.BindingResult;
19 import org.springframework.validation.FieldError;
20 import org.springframework.web.bind.annotation.ModelAttribute;
21 import org.springframework.web.bind.annotation.RequestMapping;
22 import org.springframework.web.bind.annotation.RequestMethod;
23 import org.springframework.web.bind.annotation.RequestParam;
24
25 import compbio.proteocache.users.User;
26 import compbio.proteocache.users.UserManager;
27 import compbio.cassandra.CassandraUserManager;
28
29 @Controller
30 public class UserController {
31
32         @Autowired
33         ContextSource contextSource;
34
35         // JavaMailSender mailSender;
36         private final Pattern EMAIL = Pattern.compile("[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");
37
38         @RequestMapping(value = "/register/query", method = RequestMethod.POST)
39         public String RegisterForm(ModelMap model) {
40                 User user = new User();
41                 model.addAttribute(user);
42                 return "Register";
43         }
44
45         @RequestMapping(value = "/register/edit/query", method = RequestMethod.GET)
46         public String AccountForm(ModelMap model) {
47                 User user = new User();
48                 user.setFullName("Sasha Sherstnev");
49                 user.setEmail("admin@admin.com");
50                 user.setOrganisation("UoD");
51                 user.setPosition("cleaner");
52                 user.setUpdateByEmail(true);
53                 model.addAttribute("u", user);
54                 return "Edit";
55         }
56
57         @RequestMapping(value = "/register/do", method = RequestMethod.POST)
58         public String addUser(Model model, @ModelAttribute("user") User user, BindingResult bindingResult) {
59
60                 if (bindingResult.hasErrors()) {
61                         return "Register";
62                 }
63
64                 int fullName = user.getFullName().length();
65                 if (fullName < 6 || 50 < fullName) {
66                         bindingResult.addError(new FieldError("user", "fullName", "Your full name must be between 3 and 50 symbols long!"));
67                         model.addAttribute("error", "wrong password");
68                         return "Register";
69                 }
70
71                 if (!EMAIL.matcher(user.getEmail()).find()) {
72                         bindingResult.addError(new FieldError("user", "email", "Email is empty or in a wrong form!"));
73                         model.addAttribute("error", "wrong email");
74                         return "Register";
75                 }
76
77                 int password = user.getPassword().length();
78                 if (password < 6 || 20 < password) {
79                         bindingResult.addError(new FieldError("user", "password", "The password must be at least 6 symbols long!"));
80                         model.addAttribute("error", "wrong password");
81                         return "Register";
82                 }
83
84                 int organisation = 0;
85                 if (null != user.getOrganisation())
86                         organisation = user.getOrganisation().length();
87                 if (organisation < 3 || 250 < organisation) {
88                         bindingResult.addError(new FieldError("user", "organisation", "The organisation must be between 3 and 250 symbols long!"));
89                         model.addAttribute("error", "wrong organisation name");
90                         return "Register";
91                 }
92
93                 user.setRegistrationDate(new Date());
94                 UserManager cm = new CassandraUserManager();
95                 try {
96                         cm.addUser(user);
97                 } catch (DataIntegrityViolationException e) {
98                         bindingResult.addError(new FieldError("user", "email", "This email (username) is already in use!"));
99                         model.addAttribute("error", "used email");
100                         return "Register";
101                 }
102                 if (user.isUpdateByEmail()) {
103                         subscribeToList(user.getEmail());
104                 }
105                 /*
106                  * Account.autoLogin(user, request, authenticationManager);
107                  */
108                 return "redirect:/index";
109         }
110
111         @RequestMapping(value = "/register/edit/do", method = RequestMethod.POST)
112         public String editUser(Model model, @ModelAttribute("user") User user, BindingResult bindingResult) {
113
114                 if (bindingResult.hasErrors()) {
115                         return "Register";
116                 }
117
118                 user.setRegistrationDate(new Date());
119                 UserManager cm = new CassandraUserManager();
120                 try {
121                         cm.addUser(user);
122                 } catch (DataIntegrityViolationException e) {
123                         bindingResult.addError(new FieldError("user", "email", "This email (username) is already in use!"));
124                         return "Register";
125                 }
126                 if (user.isUpdateByEmail()) {
127                         subscribeToList(user.getEmail());
128                 }
129
130                 return "redirect:/index";
131         }
132
133         private void subscribeToList(String email) {
134                 SimpleMailMessage message = new SimpleMailMessage();
135                 message.setFrom(email);
136                 message.setTo("proteocache-discuss-subscribe@compbio.dundee.ac.uk");
137                 message.setSubject("ProteoCache mailing list subscription");
138                 message.setText("testing " + email);
139                 // mailSender.send(message);
140         }
141
142         private boolean authenticate(String userDn, String credentials) {
143                 DirContext ctx = null;
144                 try {
145                         ctx = contextSource.getContext(userDn, credentials);
146                         return true;
147                 } catch (Exception e) {
148                         // Context creation failed - authentication did not succeed
149                         System.out.println("LDAP Login failed");
150                         return false;
151                 } finally {
152                         // It is imperative that the created DirContext instance is always
153                         // closed
154                         LdapUtils.closeContext(ctx);
155                 }
156         }
157
158         @RequestMapping(value = "/ldaplogindo", method = RequestMethod.POST)
159         public String LDAPlogin(Model model, @RequestParam("j_username") String username, @RequestParam("j_password") String credentials) {
160                 System.out.println("Try to authenticate with LDAP: username: " + username + ", credentials: " + credentials);
161                 if (authenticate(username, credentials)) {
162                         return "/home";
163                 }
164                 return "/public";
165         }
166
167 }