SEC-2194: Add Java Config samples

This commit is contained in:
Rob Winch
2013-08-01 14:14:18 -05:00
parent 36418b964d
commit 388a4dd9db
435 changed files with 71210 additions and 51 deletions

View File

@@ -0,0 +1,63 @@
package sample.contact;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
/**
*
* @author Luke Taylor
* @since 3.0
*/
@Controller
public class AddDeleteContactController {
@Autowired
private ContactManager contactManager;
private final Validator validator = new WebContactValidator();
/**
* Displays the "add contact" form.
*/
@RequestMapping(value="/secure/add.htm", method=RequestMethod.GET)
public ModelAndView addContactDisplay() {
return new ModelAndView("add", "webContact", new WebContact());
}
@InitBinder
public void initBinder(WebDataBinder binder) {
System.out.println("A binder for object: " + binder.getObjectName());
}
/**
* Handles the submission of the contact form, creating a new instance if
* the username and email are valid.
*/
@RequestMapping(value="/secure/add.htm", method=RequestMethod.POST)
public String addContact(WebContact form, BindingResult result) {
validator.validate(form, result);
if (result.hasErrors()) {
return "add";
}
Contact contact = new Contact(form.getName(), form.getEmail());
contactManager.create(contact);
return "redirect:/secure/index.htm";
}
@RequestMapping(value="/secure/del.htm", method=RequestMethod.GET)
public ModelAndView handleRequest(@RequestParam("contactId") int contactId) {
Contact contact = contactManager.getById(Long.valueOf(contactId));
contactManager.delete(contact);
return new ModelAndView("deleted", "contact", contact);
}
}

View File

@@ -0,0 +1,57 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import org.springframework.security.acls.domain.BasePermission;
/**
* Model object for add permission use case.
*
* @author Ben Alex
*/
public class AddPermission {
//~ Instance fields ================================================================================================
public Contact contact;
public Integer permission = BasePermission.READ.getMask();
public String recipient;
//~ Methods ========================================================================================================
public Contact getContact() {
return contact;
}
public Integer getPermission() {
return permission;
}
public String getRecipient() {
return recipient;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public void setPermission(Integer permission) {
this.permission = permission;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
}

View File

@@ -0,0 +1,59 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
/**
* Validates {@link AddPermission}.
*
* @author Ben Alex
*/
public class AddPermissionValidator implements Validator {
//~ Methods ========================================================================================================
@SuppressWarnings("unchecked")
public boolean supports(Class clazz) {
return clazz.equals(AddPermission.class);
}
public void validate(Object obj, Errors errors) {
AddPermission addPermission = (AddPermission) obj;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "permission", "err.permission", "Permission is required. *");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "recipient", "err.recipient", "Recipient is required. *");
if (addPermission.getPermission() != null) {
int permission = addPermission.getPermission().intValue();
if ((permission != BasePermission.ADMINISTRATION.getMask())
&& (permission != BasePermission.READ.getMask()) && (permission != BasePermission.DELETE.getMask())) {
errors.rejectValue("permission", "err.permission.invalid", "The indicated permission is invalid. *");
}
}
if (addPermission.getRecipient() != null) {
if (addPermission.getRecipient().length() > 100) {
errors.rejectValue("recipient", "err.recipient.length",
"The recipient is too long (maximum 100 characters). *");
}
}
}
}

View File

@@ -0,0 +1,167 @@
package sample.contact;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.DefaultPermissionFactory;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PermissionFactory;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.AclService;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.acls.model.Sid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
/**
* Web controller to handle <tt>Permission</tt> administration functions - adding and deleting
* permissions for contacts.
*
* @author Luke Taylor
* @since 3.0
*/
@Controller
@SessionAttributes("addPermission")
public final class AdminPermissionController implements MessageSourceAware{
@Autowired
private AclService aclService;
@Autowired
private ContactManager contactManager;
private MessageSourceAccessor messages;
private final Validator addPermissionValidator = new AddPermissionValidator();
private final PermissionFactory permissionFactory = new DefaultPermissionFactory();
/**
* Displays the permission admin page for a particular contact.
*/
@RequestMapping(value="/secure/adminPermission.htm", method=RequestMethod.GET)
public ModelAndView displayAdminPage(@RequestParam("contactId") int contactId) {
Contact contact = contactManager.getById(Long.valueOf(contactId));
Acl acl = aclService.readAclById(new ObjectIdentityImpl(contact));
Map<String, Object> model = new HashMap<String, Object>();
model.put("contact", contact);
model.put("acl", acl);
return new ModelAndView("adminPermission", "model", model);
}
/**
* Displays the "add permission" page for a contact.
*/
@RequestMapping(value="/secure/addPermission.htm", method=RequestMethod.GET)
public ModelAndView displayAddPermissionPageForContact(@RequestParam("contactId") int contactId) {
Contact contact = contactManager.getById(new Long(contactId));
AddPermission addPermission = new AddPermission();
addPermission.setContact(contact);
Map<String,Object> model = new HashMap<String,Object>();
model.put("addPermission", addPermission);
model.put("recipients", listRecipients());
model.put("permissions", listPermissions());
return new ModelAndView("addPermission", model);
}
@InitBinder("addPermission")
public void initBinder(WebDataBinder binder) {
binder.setAllowedFields("recipient", "permission");
}
/**
* Handles submission of the "add permission" form.
*/
@RequestMapping(value="/secure/addPermission.htm", method=RequestMethod.POST)
public String addPermission(AddPermission addPermission, BindingResult result, ModelMap model) {
addPermissionValidator.validate(addPermission, result);
if (result.hasErrors()) {
model.put("recipients", listRecipients());
model.put("permissions", listPermissions());
return "addPermission";
}
PrincipalSid sid = new PrincipalSid(addPermission.getRecipient());
Permission permission = permissionFactory.buildFromMask(addPermission.getPermission());
try {
contactManager.addPermission(addPermission.getContact(), sid, permission);
} catch (DataAccessException existingPermission) {
existingPermission.printStackTrace();
result.rejectValue("recipient", "err.recipientExistsForContact", "Addition failure.");
model.put("recipients", listRecipients());
model.put("permissions", listPermissions());
return "addPermission";
}
return "redirect:/secure/index.htm";
}
/**
* Deletes a permission
*/
@RequestMapping(value="/secure/deletePermission.htm")
public ModelAndView deletePermission(
@RequestParam("contactId") int contactId,
@RequestParam("sid") String sid,
@RequestParam("permission") int mask) {
Contact contact = contactManager.getById(new Long(contactId));
Sid sidObject = new PrincipalSid(sid);
Permission permission = permissionFactory.buildFromMask(mask);
contactManager.deletePermission(contact, sidObject, permission);
Map<String, Object> model = new HashMap<String, Object>();
model.put("contact", contact);
model.put("sid", sidObject);
model.put("permission", permission);
return new ModelAndView("deletePermission", "model", model);
}
private Map<Integer, String> listPermissions() {
Map<Integer, String> map = new LinkedHashMap<Integer, String>();
map.put(Integer.valueOf(BasePermission.ADMINISTRATION.getMask()), messages.getMessage("select.administer", "Administer"));
map.put(Integer.valueOf(BasePermission.READ.getMask()), messages.getMessage("select.read", "Read"));
map.put(Integer.valueOf(BasePermission.DELETE.getMask()), messages.getMessage("select.delete", "Delete"));
return map;
}
private Map<String, String> listRecipients() {
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("", messages.getMessage("select.pleaseSelect", "-- please select --"));
for (String recipient : contactManager.getAllRecipients()) {
map.put(recipient, recipient);
}
return map;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
}

View File

@@ -0,0 +1,140 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StopWatch;
/**
* Demonstrates accessing the {@link ContactManager} via remoting protocols.
* <p>
* Based on Spring's JPetStore sample, written by Juergen Hoeller.
*
* @author Ben Alex
*/
public class ClientApplication {
//~ Instance fields ================================================================================================
private final ListableBeanFactory beanFactory;
//~ Constructors ===================================================================================================
public ClientApplication(ListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
//~ Methods ========================================================================================================
public void invokeContactManager(Authentication authentication, int nrOfCalls) {
StopWatch stopWatch = new StopWatch(nrOfCalls + " ContactManager call(s)");
Map<String, ContactManager> contactServices = this.beanFactory.getBeansOfType(ContactManager.class, true, true);
SecurityContextHolder.getContext().setAuthentication(authentication);
for (String beanName : contactServices.keySet()) {
Object object = this.beanFactory.getBean("&" + beanName);
try {
System.out.println("Trying to find setUsername(String) method on: " + object.getClass().getName());
Method method = object.getClass().getMethod("setUsername", new Class[] {String.class});
System.out.println("Found; Trying to setUsername(String) to " + authentication.getPrincipal());
method.invoke(object, authentication.getPrincipal());
} catch (NoSuchMethodException ignored) {
System.out.println("This client proxy factory does not have a setUsername(String) method");
} catch (IllegalAccessException ignored) {
ignored.printStackTrace();
} catch (InvocationTargetException ignored) {
ignored.printStackTrace();
}
try {
System.out.println("Trying to find setPassword(String) method on: " + object.getClass().getName());
Method method = object.getClass().getMethod("setPassword", new Class[] {String.class});
method.invoke(object, authentication.getCredentials());
System.out.println("Found; Trying to setPassword(String) to " + authentication.getCredentials());
} catch (NoSuchMethodException ignored) {
System.out.println("This client proxy factory does not have a setPassword(String) method");
} catch (IllegalAccessException ignored) {}
catch (InvocationTargetException ignored) {}
ContactManager remoteContactManager = contactServices.get(beanName);
System.out.println("Calling ContactManager '" + beanName + "'");
stopWatch.start(beanName);
List<Contact> contacts = null;
for (int i = 0; i < nrOfCalls; i++) {
contacts = remoteContactManager.getAll();
}
stopWatch.stop();
if (contacts.size() != 0) {
for(Contact contact : contacts) {
System.out.println("Contact: " + contact);
}
} else {
System.out.println("No contacts found which this user has permission to");
}
System.out.println();
System.out.println(stopWatch.prettyPrint());
}
SecurityContextHolder.clearContext();
}
public static void main(String[] args) {
String username = System.getProperty("username", "");
String password = System.getProperty("password", "");
String nrOfCallsString = System.getProperty("nrOfCalls", "");
if ("".equals(username) || "".equals(password)) {
System.out.println(
"You need to specify the user ID to use, the password to use, and optionally a number of calls "
+ "using the username, password, and nrOfCalls system properties respectively. eg for user rod, "
+ "use: -Dusername=rod -Dpassword=koala' for a single call per service and "
+ "use: -Dusername=rod -Dpassword=koala -DnrOfCalls=10 for ten calls per service.");
System.exit(-1);
} else {
int nrOfCalls = 1;
if (!"".equals(nrOfCallsString)) {
nrOfCalls = Integer.parseInt(nrOfCallsString);
}
ListableBeanFactory beanFactory = new FileSystemXmlApplicationContext("clientContext.xml");
ClientApplication client = new ClientApplication(beanFactory);
client.invokeContactManager(new UsernamePasswordAuthenticationToken(username, password), nrOfCalls);
System.exit(0);
}
}
}

View File

@@ -0,0 +1,92 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import java.io.Serializable;
/**
* Represents a contact.
*
* @author Ben Alex
*/
public class Contact implements Serializable {
//~ Instance fields ================================================================================================
private Long id;
private String email;
private String name;
//~ Constructors ===================================================================================================
public Contact(String name, String email) {
this.name = name;
this.email = email;
}
public Contact() {}
//~ Methods ========================================================================================================
/**
* @return Returns the email.
*/
public String getEmail() {
return email;
}
/**
* @return Returns the id.
*/
public Long getId() {
return id;
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param email The email to set.
*/
public void setEmail(String email) {
this.email = email;
}
public void setId(Long id) {
this.id = id;
}
/**
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString() + ": ");
sb.append("Id: " + this.getId() + "; ");
sb.append("Name: " + this.getName() + "; ");
sb.append("Email: " + this.getEmail());
return sb.toString();
}
}

View File

@@ -0,0 +1,42 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import java.util.List;
/**
* Provides access to the application's persistence layer.
*
* @author Ben Alex
*/
public interface ContactDao {
//~ Methods ========================================================================================================
public void create(Contact contact);
public void delete(Long contactId);
public List<Contact> findAll();
public List<String> findAllPrincipals();
public List<String> findAllRoles();
public Contact getById(Long id);
public void update(Contact contact);
}

View File

@@ -0,0 +1,105 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
/**
* Base implementation of {@link ContactDao} that uses Spring's JdbcTemplate.
*
* @author Ben Alex
* @author Luke Taylor
*/
public class ContactDaoSpring extends JdbcDaoSupport implements ContactDao {
//~ Methods ========================================================================================================
public void create(final Contact contact) {
getJdbcTemplate().update("insert into contacts values (?, ?, ?)", new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setLong(1, contact.getId());
ps.setString(2, contact.getName());
ps.setString(3, contact.getEmail());
}
});
}
public void delete(final Long contactId) {
getJdbcTemplate().update("delete from contacts where id = ?", new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setLong(1, contactId);
}
});
}
public void update(final Contact contact) {
getJdbcTemplate().update("update contacts set contact_name = ?, address = ? where id = ?", new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(1, contact.getName());
ps.setString(2, contact.getEmail());
ps.setLong(3, contact.getId());
}
});
}
public List<Contact> findAll() {
return getJdbcTemplate().query("select id, contact_name, email from contacts order by id", new RowMapper<Contact>() {
public Contact mapRow(ResultSet rs, int rowNum) throws SQLException {
return mapContact(rs);
}
});
}
public List<String> findAllPrincipals() {
return getJdbcTemplate().queryForList("select username from users order by username", String.class);
}
public List<String> findAllRoles() {
return getJdbcTemplate().queryForList("select distinct authority from authorities order by authority", String.class);
}
public Contact getById(Long id) {
List<Contact> list = getJdbcTemplate().query("select id, contact_name, email from contacts where id = ? order by id", new RowMapper<Contact>() {
public Contact mapRow(ResultSet rs, int rowNum) throws SQLException {
return mapContact(rs);
}
}, id);
if (list.size() == 0) {
return null;
} else {
return (Contact) list.get(0);
}
}
private Contact mapContact(ResultSet rs) throws SQLException {
Contact contact = new Contact();
contact.setId(new Long(rs.getLong("id")));
contact.setName(rs.getString("contact_name"));
contact.setEmail(rs.getString("email"));
return contact;
}
}

View File

@@ -0,0 +1,57 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.acls.model.Sid;
import java.util.List;
/**
* Interface for the application's services layer.
*
* @author Ben Alex
*/
public interface ContactManager {
//~ Methods ========================================================================================================
@PreAuthorize("hasPermission(#contact, admin)")
public void addPermission(Contact contact, Sid recipient, Permission permission);
@PreAuthorize("hasPermission(#contact, admin)")
public void deletePermission(Contact contact, Sid recipient, Permission permission);
@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);
@PreAuthorize("hasPermission(#contact, 'delete') or hasPermission(#contact, admin)")
public void delete(Contact contact);
@PreAuthorize("hasRole('ROLE_USER')")
@PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, admin)")
public List<Contact> getAll();
@PreAuthorize("hasRole('ROLE_USER')")
public List<String> getAllRecipients();
@PreAuthorize(
"hasPermission(#id, 'sample.contact.Contact', read) or " +
"hasPermission(#id, 'sample.contact.Contact', admin)")
public Contact getById(Long id);
public Contact getRandomContact();
}

View File

@@ -0,0 +1,186 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.AccessControlEntry;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.security.acls.model.NotFoundException;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.util.Assert;
import java.util.List;
import java.util.Random;
/**
* Concrete implementation of {@link ContactManager}.
*
* @author Ben Alex
*/
@Transactional
public class ContactManagerBackend extends ApplicationObjectSupport implements ContactManager, InitializingBean {
//~ Instance fields ================================================================================================
private ContactDao contactDao;
private MutableAclService mutableAclService;
private int counter = 1000;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(contactDao, "contactDao required");
Assert.notNull(mutableAclService, "mutableAclService required");
}
public void addPermission(Contact contact, Sid recipient, Permission permission) {
MutableAcl acl;
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
try {
acl = (MutableAcl) mutableAclService.readAclById(oid);
} catch (NotFoundException nfe) {
acl = mutableAclService.createAcl(oid);
}
acl.insertAce(acl.getEntries().size(), permission, recipient, true);
mutableAclService.updateAcl(acl);
logger.debug("Added permission " + permission + " for Sid " + recipient + " contact " + contact);
}
public void create(Contact contact) {
// Create the Contact itself
contact.setId(new Long(counter++));
contactDao.create(contact);
// Grant the current principal administrative permission to the contact
addPermission(contact, new PrincipalSid(getUsername()), BasePermission.ADMINISTRATION);
if (logger.isDebugEnabled()) {
logger.debug("Created contact " + contact + " and granted admin permission to recipient " + getUsername());
}
}
public void delete(Contact contact) {
contactDao.delete(contact.getId());
// Delete the ACL information as well
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
mutableAclService.deleteAcl(oid, false);
if (logger.isDebugEnabled()) {
logger.debug("Deleted contact " + contact + " including ACL permissions");
}
}
public void deletePermission(Contact contact, Sid recipient, Permission permission) {
ObjectIdentity oid = new ObjectIdentityImpl(Contact.class, contact.getId());
MutableAcl acl = (MutableAcl) mutableAclService.readAclById(oid);
// Remove all permissions associated with this particular recipient (string equality to KISS)
List<AccessControlEntry> entries = acl.getEntries();
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getSid().equals(recipient) && entries.get(i).getPermission().equals(permission)) {
acl.deleteAce(i);
}
}
mutableAclService.updateAcl(acl);
if (logger.isDebugEnabled()) {
logger.debug("Deleted contact " + contact + " ACL permissions for recipient " + recipient);
}
}
@Transactional(readOnly=true)
public List<Contact> getAll() {
logger.debug("Returning all contacts");
return contactDao.findAll();
}
@Transactional(readOnly=true)
public List<String> getAllRecipients() {
logger.debug("Returning all recipients");
return contactDao.findAllPrincipals();
}
@Transactional(readOnly=true)
public Contact getById(Long id) {
if (logger.isDebugEnabled()) {
logger.debug("Returning contact with id: " + id);
}
return contactDao.getById(id);
}
/**
* This is a public method.
*/
@Transactional(readOnly=true)
public Contact getRandomContact() {
logger.debug("Returning random contact");
Random rnd = new Random();
List<Contact> contacts = contactDao.findAll();
int getNumber = rnd.nextInt(contacts.size());
return contacts.get(getNumber);
}
protected String getUsername() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth.getPrincipal() instanceof UserDetails) {
return ((UserDetails) auth.getPrincipal()).getUsername();
} else {
return auth.getPrincipal().toString();
}
}
public void setContactDao(ContactDao contactDao) {
this.contactDao = contactDao;
}
public void setMutableAclService(MutableAclService mutableAclService) {
this.mutableAclService = mutableAclService;
}
public void update(Contact contact) {
contactDao.update(contact);
logger.debug("Updated contact " + contact);
}
}

View File

@@ -0,0 +1,285 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import java.util.Random;
import javax.sql.DataSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.acls.domain.AclImpl;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
/**
* Populates the Contacts in-memory database with contact and ACL information.
*
* @author Ben Alex
*/
public class DataSourcePopulator implements InitializingBean {
//~ Instance fields ================================================================================================
JdbcTemplate template;
private MutableAclService mutableAclService;
final Random rnd = new Random();
TransactionTemplate tt;
final String[] firstNames = {
"Bob", "Mary", "James", "Jane", "Kristy", "Kirsty", "Kate", "Jeni", "Angela", "Melanie", "Kent", "William",
"Geoff", "Jeff", "Adrian", "Amanda", "Lisa", "Elizabeth", "Prue", "Richard", "Darin", "Phillip", "Michael",
"Belinda", "Samantha", "Brian", "Greg", "Matthew"
};
final String[] lastNames = {
"Smith", "Williams", "Jackson", "Rictor", "Nelson", "Fitzgerald", "McAlpine", "Sutherland", "Abbott", "Hall",
"Edwards", "Gates", "Black", "Brown", "Gray", "Marwell", "Booch", "Johnson", "McTaggart", "Parklin",
"Findlay", "Robinson", "Giugni", "Lang", "Chi", "Carmichael"
};
private int createEntities = 50;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(mutableAclService, "mutableAclService required");
Assert.notNull(template, "dataSource required");
Assert.notNull(tt, "platformTransactionManager required");
// Set a user account that will initially own all the created data
Authentication authRequest = new UsernamePasswordAuthenticationToken("rod", "koala",
AuthorityUtils.createAuthorityList("ROLE_IGNORED"));
SecurityContextHolder.getContext().setAuthentication(authRequest);
try {
template.execute("DROP TABLE CONTACTS");
template.execute("DROP TABLE AUTHORITIES");
template.execute("DROP TABLE USERS");
template.execute("DROP TABLE ACL_ENTRY");
template.execute("DROP TABLE ACL_OBJECT_IDENTITY");
template.execute("DROP TABLE ACL_CLASS");
template.execute("DROP TABLE ACL_SID");
} catch(Exception e) {
System.out.println("Failed to drop tables: " + e.getMessage());
}
template.execute(
"CREATE TABLE ACL_SID(" +
"ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
"PRINCIPAL BOOLEAN NOT NULL," +
"SID VARCHAR_IGNORECASE(100) NOT NULL," +
"CONSTRAINT UNIQUE_UK_1 UNIQUE(SID,PRINCIPAL));");
template.execute(
"CREATE TABLE ACL_CLASS(" +
"ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
"CLASS VARCHAR_IGNORECASE(100) NOT NULL," +
"CONSTRAINT UNIQUE_UK_2 UNIQUE(CLASS));");
template.execute(
"CREATE TABLE ACL_OBJECT_IDENTITY(" +
"ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
"OBJECT_ID_CLASS BIGINT NOT NULL," +
"OBJECT_ID_IDENTITY BIGINT NOT NULL," +
"PARENT_OBJECT BIGINT," +
"OWNER_SID BIGINT," +
"ENTRIES_INHERITING BOOLEAN NOT NULL," +
"CONSTRAINT UNIQUE_UK_3 UNIQUE(OBJECT_ID_CLASS,OBJECT_ID_IDENTITY)," +
"CONSTRAINT FOREIGN_FK_1 FOREIGN KEY(PARENT_OBJECT)REFERENCES ACL_OBJECT_IDENTITY(ID)," +
"CONSTRAINT FOREIGN_FK_2 FOREIGN KEY(OBJECT_ID_CLASS)REFERENCES ACL_CLASS(ID)," +
"CONSTRAINT FOREIGN_FK_3 FOREIGN KEY(OWNER_SID)REFERENCES ACL_SID(ID));");
template.execute(
"CREATE TABLE ACL_ENTRY(" +
"ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY," +
"ACL_OBJECT_IDENTITY BIGINT NOT NULL,ACE_ORDER INT NOT NULL,SID BIGINT NOT NULL," +
"MASK INTEGER NOT NULL,GRANTING BOOLEAN NOT NULL,AUDIT_SUCCESS BOOLEAN NOT NULL," +
"AUDIT_FAILURE BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_4 UNIQUE(ACL_OBJECT_IDENTITY,ACE_ORDER)," +
"CONSTRAINT FOREIGN_FK_4 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID)," +
"CONSTRAINT FOREIGN_FK_5 FOREIGN KEY(SID) REFERENCES ACL_SID(ID));");
template.execute(
"CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL);");
template.execute(
"CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));");
template.execute("CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);");
template.execute(
"CREATE TABLE CONTACTS(ID BIGINT NOT NULL PRIMARY KEY, CONTACT_NAME VARCHAR_IGNORECASE(50) NOT NULL, EMAIL VARCHAR_IGNORECASE(50) NOT NULL)");
/*
Passwords encoded using MD5, NOT in Base64 format, with null as salt
Encoded password for rod is "koala"
Encoded password for dianne is "emu"
Encoded password for scott is "wombat"
Encoded password for peter is "opal" (but user is disabled)
Encoded password for bill is "wombat"
Encoded password for bob is "wombat"
Encoded password for jane is "wombat"
*/
template.execute("INSERT INTO USERS VALUES('rod','$2a$10$75pBjapg4Nl8Pzd.3JRnUe7PDJmk9qBGwNEJDAlA3V.dEJxcDKn5O',TRUE);");
template.execute("INSERT INTO USERS VALUES('dianne','$2a$04$bCMEyxrdF/7sgfUiUJ6Ose2vh9DAMaVBldS1Bw2fhi1jgutZrr9zm',TRUE);");
template.execute("INSERT INTO USERS VALUES('scott','$2a$06$eChwvzAu3TSexnC3ynw4LOSw1qiEbtNItNeYv5uI40w1i3paoSfLu',TRUE);");
template.execute("INSERT INTO USERS VALUES('peter','$2a$04$8.H8bCMROLF4CIgd7IpeQ.tcBXLP5w8iplO0n.kCIkISwrIgX28Ii',FALSE);");
template.execute("INSERT INTO USERS VALUES('bill','$2a$04$8.H8bCMROLF4CIgd7IpeQ.3khQlPVNWbp8kzSQqidQHGFurim7P8O',TRUE);");
template.execute("INSERT INTO USERS VALUES('bob','$2a$06$zMgxlMf01SfYNcdx7n4NpeFlAGU8apCETz/i2C7VlYWu6IcNyn4Ay',TRUE);");
template.execute("INSERT INTO USERS VALUES('jane','$2a$05$ZrdS7yMhCZ1J.AAidXZhCOxdjD8LO/dhlv4FJzkXA6xh9gdEbBT/u',TRUE);");
template.execute("INSERT INTO AUTHORITIES VALUES('rod','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('rod','ROLE_SUPERVISOR');");
template.execute("INSERT INTO AUTHORITIES VALUES('dianne','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('scott','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('peter','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('bill','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('bob','ROLE_USER');");
template.execute("INSERT INTO AUTHORITIES VALUES('jane','ROLE_USER');");
template.execute("INSERT INTO contacts VALUES (1, 'John Smith', 'john@somewhere.com');");
template.execute("INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael@xyz.com');");
template.execute("INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe@demo.com');");
template.execute("INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen@sutherland.com');");
template.execute("INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell@abcdef.com');");
template.execute("INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose@xyz.com');");
template.execute("INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda@abcdef.com');");
template.execute("INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy@smith.com');");
template.execute("INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan@xyz.com');");
for (int i = 10; i < createEntities; i++) {
String[] person = selectPerson();
template.execute("INSERT INTO contacts VALUES (" + i + ", '" + person[2] + "', '" + person[0].toLowerCase()
+ "@" + person[1].toLowerCase() + ".com');");
}
// Create acl_object_identity rows (and also acl_class rows as needed
for (int i = 1; i < createEntities; i++) {
final ObjectIdentity objectIdentity = new ObjectIdentityImpl(Contact.class, new Long(i));
tt.execute(new TransactionCallback<Object>() {
public Object doInTransaction(TransactionStatus arg0) {
mutableAclService.createAcl(objectIdentity);
return null;
}
});
}
// Now grant some permissions
grantPermissions(1, "rod", BasePermission.ADMINISTRATION);
grantPermissions(2, "rod", BasePermission.READ);
grantPermissions(3, "rod", BasePermission.READ);
grantPermissions(3, "rod", BasePermission.WRITE);
grantPermissions(3, "rod", BasePermission.DELETE);
grantPermissions(4, "rod", BasePermission.ADMINISTRATION);
grantPermissions(4, "dianne", BasePermission.ADMINISTRATION);
grantPermissions(4, "scott", BasePermission.READ);
grantPermissions(5, "dianne", BasePermission.ADMINISTRATION);
grantPermissions(5, "dianne", BasePermission.READ);
grantPermissions(6, "dianne", BasePermission.READ);
grantPermissions(6, "dianne", BasePermission.WRITE);
grantPermissions(6, "dianne", BasePermission.DELETE);
grantPermissions(6, "scott", BasePermission.READ);
grantPermissions(7, "scott", BasePermission.ADMINISTRATION);
grantPermissions(8, "dianne", BasePermission.ADMINISTRATION);
grantPermissions(8, "dianne", BasePermission.READ);
grantPermissions(8, "scott", BasePermission.READ);
grantPermissions(9, "scott", BasePermission.ADMINISTRATION);
grantPermissions(9, "scott", BasePermission.READ);
grantPermissions(9, "scott", BasePermission.WRITE);
grantPermissions(9, "scott", BasePermission.DELETE);
// Now expressly change the owner of the first ten contacts
// We have to do this last, because "rod" owns all of them (doing it sooner would prevent ACL updates)
// Note that ownership has no impact on permissions - they're separate (ownership only allows ACl editing)
changeOwner(5, "dianne");
changeOwner(6, "dianne");
changeOwner(7, "scott");
changeOwner(8, "dianne");
changeOwner(9, "scott");
String[] users = {"bill", "bob", "jane"}; // don't want to mess around with consistent sample data
Permission[] permissions = {BasePermission.ADMINISTRATION, BasePermission.READ, BasePermission.DELETE};
for (int i = 10; i < createEntities; i++) {
String user = users[rnd.nextInt(users.length)];
Permission permission = permissions[rnd.nextInt(permissions.length)];
grantPermissions(i, user, permission);
String user2 = users[rnd.nextInt(users.length)];
Permission permission2 = permissions[rnd.nextInt(permissions.length)];
grantPermissions(i, user2, permission2);
}
SecurityContextHolder.clearContext();
}
private void changeOwner(int contactNumber, String newOwnerUsername) {
AclImpl acl = (AclImpl) mutableAclService.readAclById(new ObjectIdentityImpl(Contact.class,
new Long(contactNumber)));
acl.setOwner(new PrincipalSid(newOwnerUsername));
updateAclInTransaction(acl);
}
public int getCreateEntities() {
return createEntities;
}
private void grantPermissions(int contactNumber, String recipientUsername, Permission permission) {
AclImpl acl = (AclImpl) mutableAclService.readAclById(new ObjectIdentityImpl(Contact.class,
new Long(contactNumber)));
acl.insertAce(acl.getEntries().size(), permission, new PrincipalSid(recipientUsername), true);
updateAclInTransaction(acl);
}
private String[] selectPerson() {
String firstName = firstNames[rnd.nextInt(firstNames.length)];
String lastName = lastNames[rnd.nextInt(lastNames.length)];
return new String[] {firstName, lastName, firstName + " " + lastName};
}
public void setCreateEntities(int createEntities) {
this.createEntities = createEntities;
}
public void setDataSource(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
public void setMutableAclService(MutableAclService mutableAclService) {
this.mutableAclService = mutableAclService;
}
public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
this.tt = new TransactionTemplate(platformTransactionManager);
}
private void updateAclInTransaction(final MutableAcl acl) {
tt.execute(new TransactionCallback<Object>() {
public Object doInTransaction(TransactionStatus arg0) {
mutableAclService.updateAcl(acl);
return null;
}
});
}
}

View File

@@ -0,0 +1,82 @@
package sample.contact;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.acls.AclPermissionEvaluator;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
* Controller which handles simple, single request use cases such as index pages and contact deletion.
*
* @author Luke Taylor
* @since 3.0
*/
@Controller
public class IndexController {
private final static Permission[] HAS_DELETE = new Permission[] {BasePermission.DELETE, BasePermission.ADMINISTRATION};
private final static Permission[] HAS_ADMIN = new Permission[] {BasePermission.ADMINISTRATION};
//~ Instance fields ================================================================================================
@Autowired
private ContactManager contactManager;
@Autowired
private PermissionEvaluator permissionEvaluator;
//~ Methods ========================================================================================================
/**
* The public index page, used for unauthenticated users.
*/
@RequestMapping(value="/hello.htm", method=RequestMethod.GET)
public ModelAndView displayPublicIndex() {
Contact rnd = contactManager.getRandomContact();
return new ModelAndView("hello", "contact", rnd);
}
/**
* The index page for an authenticated user.
* <p>
* This controller displays a list of all the contacts for which the current user has read or admin permissions.
* It makes a call to {@link ContactManager#getAll()} which automatically filters the returned list using Spring
* Security's ACL mechanism (see the expression annotations on this interface for the details).
* <p>
* In addition to rendering the list of contacts, the view will also include a "Del" or "Admin" link beside the
* contact, depending on whether the user has the corresponding permissions (admin permission is assumed to imply
* delete here). This information is stored in the model using the injected {@link PermissionEvaluator} instance.
* The implementation should be an instance of {@link AclPermissionEvaluator} or one which is compatible with Spring
* Security's ACL module.
*/
@RequestMapping(value="/secure/index.htm", method=RequestMethod.GET)
public ModelAndView displayUserContacts() {
List<Contact> myContactsList = contactManager.getAll();
Map<Contact, Boolean> hasDelete = new HashMap<Contact, Boolean>(myContactsList.size());
Map<Contact, Boolean> hasAdmin = new HashMap<Contact, Boolean>(myContactsList.size());
Authentication user = SecurityContextHolder.getContext().getAuthentication();
for (Contact contact : myContactsList) {
hasDelete.put(contact, Boolean.valueOf(permissionEvaluator.hasPermission(user, contact, HAS_DELETE)));
hasAdmin.put(contact, Boolean.valueOf(permissionEvaluator.hasPermission(user, contact, HAS_ADMIN)));
}
Map<String, Object> model = new HashMap<String, Object>();
model.put("contacts", myContactsList);
model.put("hasDeletePermission", hasDelete);
model.put("hasAdminPermission", hasAdmin);
return new ModelAndView("index", "model", model);
}
}

View File

@@ -0,0 +1,46 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
/**
* An object that represents user-editable sections of a {@link Contact}.
*
* @author Ben Alex
*/
public class WebContact {
//~ Instance fields ================================================================================================
private String email;
private String name;
//~ Methods ========================================================================================================
public String getEmail() {
return email;
}
public String getName() {
return name;
}
public void setEmail(String email) {
this.email = email;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,46 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.contact;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* Validates {@link WebContact}.
*
* @author Ben Alex
*/
public class WebContactValidator implements Validator {
//~ Methods ========================================================================================================
@SuppressWarnings("unchecked")
public boolean supports(Class clazz) {
return clazz.equals(WebContact.class);
}
public void validate(Object obj, Errors errors) {
WebContact wc = (WebContact) obj;
if ((wc.getName() == null) || (wc.getName().length() < 3) || (wc.getName().length() > 50)) {
errors.rejectValue("name", "err.name", "Name 3-50 characters is required. *");
}
if ((wc.getEmail() == null) || (wc.getEmail().length() < 3) || (wc.getEmail().length() > 50)) {
errors.rejectValue("email", "err.email", "Email 3-50 characters is required. *");
}
}
}